Thursday 10 October 2019

DISPLAY ALV LIST EASILY IN ABAP USING CL_SALV_TABLE


************************************************************************
* GLOBAL DATA DEFINITIONS                                              *
************************************************************************
*----------------------------------------------------------------------*
* INCLUDE - definitions                                                *
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* CONSTANT - definitions                                               *
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* TYPE - definitions                                                   *
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* DDIC - TABLE / STRUCTURE / VIEW definitions                          *
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* STRUCTURE definitions                                                *
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* RANGE definitions                                                    *
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* REFERENCE definitions                                                *
*----------------------------------------------------------------------*
DATA alv     TYPE REF TO cl_salv_table.
DATA columns TYPE REF TO cl_salv_columns_table.
DATA column  TYPE REF TO cl_salv_column.

*----------------------------------------------------------------------*
* INTERNAL TABLE definitions                                           *
*----------------------------------------------------------------------*
DATA flight_schedule TYPE STANDARD TABLE OF spfli.

*----------------------------------------------------------------------*
* OTHER GLOBAL DATA definitions                                        *
*----------------------------------------------------------------------*
************************************************************************
* GLOBAL DATA DEFINITIONS - END                                        *
************************************************************************

************************************************************************
* SELECTION SCREENS                                                    *
************************************************************************
************************************************************************
* SELECTION SCREENS - END                                              *
************************************************************************

************************************************************************
* EVENTS                                                               *
************************************************************************
*----------------------------------------------------------------------*
* INITIALIZATON event                                                  *
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* AT SELECTION-SCREEN ON VALUE-REQUEST FOR event                       *
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* START-OF-SELECTION event                                             *
*----------------------------------------------------------------------*
START-OF-SELECTION.
  PERFORM get_flight_schedule.

  PERFORM initialize_alv.

  PERFORM display_alv.

*----------------------------------------------------------------------*
* END-OF-SELECTION event                                               *
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* AT LINE-SELECTION event                                              *
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* AT USER-COMMAND event                                                *
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* TOP-OF-PAGE event                                                    *
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* END-OF-PAGE event                                                    *
*----------------------------------------------------------------------*
************************************************************************
* EVENTS - END                                                         *
************************************************************************

************************************************************************
* SUBROUTINES                                                          *
************************************************************************
*&---------------------------------------------------------------------*
FORM get_flight_schedule.
*&---------------------------------------------------------------------*
  SELECT FROM spfli INTO TABLE flight_schedule UP TO 100 ROWS.
ENDFORM.                    " GET_FLIGHT_SCHEDULE

*&---------------------------------------------------------------------*
FORM initialize_alv.
*&---------------------------------------------------------------------*
  DATA message   TYPE REF TO cx_salv_msg.

  TRY.
      cl_salv_table=>factory(
      IMPORTING
        r_salv_table alv
      CHANGING
        t_table      flight_schedule ).

      columns alv->get_columns).

      PERFORM enable_layout_settings.
      PERFORM optimize_column_width.
      PERFORM hide_client_column.
      PERFORM set_departure_country_column.
      PERFORM set_toolbar.
      PERFORM display_settings.
      " ...
      " PERFORM setting_n.

    CATCH cx_salv_msg INTO message.
      " error handling
  ENDTRY.
ENDFORM.                    " INITIALIZE_ALV

*&---------------------------------------------------------------------*
FORM display_alv.
*&---------------------------------------------------------------------*
  alv->display).
ENDFORM.                    " DISPLAY_ALV

*&---------------------------------------------------------------------*
FORM enable_layout_settings.
*&---------------------------------------------------------------------*
  DATA layout_settings TYPE REF TO cl_salv_layout.
  DATA layout_key      TYPE salv_s_layout_key.

  layout_settings alv->get_layout).

  layout_key-report sy-repid.
  layout_settings->set_keylayout_key ).

  layout_settings->set_save_restrictionif_salv_c_layout=>restrict_none ).
ENDFORM.                    "ENABLE_LAYOUT_SETTINGS

*&---------------------------------------------------------------------*
FORM optimize_column_width.
*&---------------------------------------------------------------------*
  columns->set_optimize).
ENDFORM.                    "OPTIMIZE_COLUMN_WIDTH

*&---------------------------------------------------------------------*
FORM hide_client_column.
*&---------------------------------------------------------------------*
  DATA not_found TYPE REF TO cx_salv_not_found.

  TRY.
      column columns->get_column'MANDT' ).
      column->set_visibleif_salv_c_bool_sap=>false ).
    CATCH cx_salv_not_found INTO not_found.
      " error handling
  ENDTRY.
ENDFORM.                    " HIDE_CLIENT_COLUMN

*&---------------------------------------------------------------------*
FORM set_departure_country_column.
*&---------------------------------------------------------------------*
  DATA not_found TYPE REF TO cx_salv_not_found.

  TRY.
      column columns->get_column'COUNTRYFR' ).
      column->set_short_text'D. Country' ).
      column->set_medium_text'Dep. Country' ).
      column->set_long_text'Departure Country' ).
    CATCH cx_salv_not_found INTO not_found.
      " error handling
  ENDTRY.
ENDFORM.                    " SET_DEPARTURE_COUNTRY_COLUMN

*&---------------------------------------------------------------------*
FORM set_toolbar.
*&---------------------------------------------------------------------*
  DATA functions TYPE REF TO cl_salv_functions_list.

  functions alv->get_functions).
  functions->set_all).
ENDFORM.                    " SET_TOOLBAR

*&---------------------------------------------------------------------*
FORM display_settings.
*&---------------------------------------------------------------------*
  DATA display_settings TYPE REF TO cl_salv_display_settings.

  display_settings alv->get_display_settings).
  display_settings->set_striped_patternif_salv_c_bool_sap=>true ).
  display_settings->set_list_header'Flight Schedule' ).
ENDFORM.                    " DISPLAY_SETTINGS

************************************************************************
* SUBROUTINES - END                                                    *
************************************************************************

Thursday 1 August 2019

Select Dynamically Specific Material Master View BDC for Material Master (MM02)

Creating a BDC of the MM02 will not be an easy task. As soon as we enter the material and hit enter it will ask us to choose the required Material master views. This popup contains the available material master views and they are not constant. Sometimes MRP1 comes at the 12th line and sometimes it comes to 6th line. This dynamic of the views are solely depended on the Status (MARA-VPSTA).
To overcome of this dynamics we need to get to know where exactly our required view will appear e.g. line 6 or line 10 or line 15. We will use the FM SELECTION_VIEWS_FIND to find out which view will come at which position.
In our BDC, we will follow these steps:
1. Always select the Basic Data 1
2. Get the respective user command for the tab by Executing the FM SELECTION_VIEWS_FIND.
Status (MARA-VPSTA) contains the combination of the View indicator. You can find the relation of the status indicator and view name in the documentation of the data element PSTAT_D or follow this table:
User department Maintenance status 
 
Work scheduling                                                      A
Accounting                                                               B
Classification                                                            C
MRP                                                                            D
Purchasing                                                                E
Production resources/tools                                     F
Costing                                                                      G
Basic data                                                                  K
Storage                                                                       L
Forecasting                                                                P
Quality management                                                Q
Warehouse management                                         S
Sales                                                                          V
Plant stocks                                                              X
Storage location stocks                                          Z

In this my test BDC, I want to update the MRP type. MRP type comes under the “MRP 1″ view of the material master. So, I will first select the Basic Data and than move to MRP 1 view and update the MRP type.
Code Snippet to Select View in MM02

Error rendering macro 'code': Invalid value specified for parameter 'lang'
* Local data
DATA:   messtab LIKE bdcmsgcoll OCCURS 0 WITH HEADER LINE.
DATA:   bdcdata LIKE bdcdata    OCCURS 0 WITH HEADER LINE.

* Selection Screen
PARAMETERS: p_matnr TYPE mara-matnr OBLIGATORY,
            p_werks TYPE marc-werks OBLIGATORY,
            p_lgort TYPE rmmg1-lgort OBLIGATORY,
            p_dismm TYPE marc-dismm OBLIGATORY.

START-OF-SELECTION.

* Material views ....................................................
  DATA:  l_vpsta LIKE t130m-pstat.

  SELECT SINGLE vpsta
         INTO   l_vpsta
         FROM   mara
         WHERE  matnr = p_matnr.

* Get View sequence .................................................
  DATA: l_bild  LIKE t133a-bilds,
        lt_bild LIKE mbildtab OCCURS 0 WITH HEADER LINE.

* Screen Sequence for Standard Industry tab pages in material master
  l_bild = '21'.

* Get screen sequence
  CALL FUNCTION 'SELECTION_VIEWS_FIND'
    EXPORTING
      bildsequenz     = l_bild
      pflegestatus    = l_vpsta
    TABLES
      bildtab         = lt_bild
    EXCEPTIONS
      call_wrong      = 1
      empty_selection = 2
      OTHERS          = 3.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
*
* Get the Tab page for MRP1 .........................................
  DATA: l_tab_mrp1 TYPE sy-ucomm.
*
* reading table with MRP view
  READ TABLE lt_bild WITH KEY pstat = 'D'.
  IF sy-subrc = 0.
    l_tab_mrp1 = lt_bild-guifu.
  ENDIF.

* make ok code for the MRP1
  CONCATENATE '=' l_tab_mrp1 INTO l_tab_mrp1.

* BDC ...............................................................
  PERFORM bdc_dynpro      USING 'SAPLMGMM'          '0060'.
  PERFORM bdc_field       USING 'RMMG1-MATNR'       p_matnr.
  PERFORM bdc_field       USING 'BDC_OKCODE'        '=ENTR'.
  PERFORM bdc_dynpro      USING 'SAPLMGMM'          '0070'.
  PERFORM bdc_field       USING 'MSICHTAUSW-KZSEL(01)' 'X'.
  PERFORM bdc_field       USING 'BDC_OKCODE'        '=ENTR'.
  PERFORM bdc_dynpro      USING 'SAPLMGMM'          '4004'.
  PERFORM bdc_field       USING 'BDC_OKCODE'        l_tab_mrp1.
  PERFORM bdc_dynpro      USING 'SAPLMGMM'          '0081'.
  PERFORM bdc_field       USING 'RMMG1-WERKS'       p_werks.
  PERFORM bdc_field       USING 'RMMG1-LGORT'       p_lgort.
  PERFORM bdc_field       USING 'BDC_OKCODE'        '=ENTR'.
  PERFORM bdc_dynpro      USING 'SAPLMGMM'          '4000'.
  PERFORM bdc_field       USING 'MARC-DISMM'        p_dismm.
  PERFORM bdc_field       USING 'BDC_OKCODE'       '=BU'.

  PERFORM bdc_transaction USING 'MM02'.
*
*&---------------------------------------------------------------------*
*&      Form  BDC_DYNPRO
*&---------------------------------------------------------------------*
FORM bdc_dynpro USING p_program
                      p_screen.
*
  MOVE: p_program TO bdcdata-program,
        p_screen  TO bdcdata-dynpro,
        'X'       TO bdcdata-dynbegin.
*
  APPEND bdcdata.
  CLEAR  bdcdata.
*
ENDFORM.                    " BDC_DYNPRO
*
*&---------------------------------------------------------------------*
*&      Form  BDC_FIELD
*&---------------------------------------------------------------------*
FORM bdc_field USING p_field_name
                     p_field_value.
*
  MOVE: p_field_name  TO bdcdata-fnam,
        p_field_value TO bdcdata-fval.
*
  APPEND bdcdata.
  CLEAR  bdcdata.
*
ENDFORM.                    " BDC_FIELD
*
*
*&---------------------------------------------------------------------*
*&      Form  BDC_TRANSACTION
*&---------------------------------------------------------------------*
FORM bdc_transaction USING tcode.
  DATA: l_mstring(480).
  DATA: l_subrc LIKE sy-subrc.
* batch input session
  REFRESH messtab.
  CALL TRANSACTION tcode USING bdcdata
                   MODE   'A'
                   "A: show all dynpros
                   "E: show dynpro on error only
                   "N: do not display dynpro
*
                   UPDATE 'L'
                   MESSAGES INTO messtab.
  REFRESH bdcdata.
ENDFORM.                    "BDC_TRANSACTION

Tuesday 16 July 2019

SAP S/4HANA Integration with WhatsApp

Welcome to my another blog, here i am going to discuss on one of my cool project ‘Whatsapp integration with S/4HANA’. We all know most probably whatsapp is one of most used messaging app now a day people use for business as well as personal use.
But How this integration make sense?
Answer is very simple think about a situation where you want to know your order status, either you would login to system or you ask someone. Now instead of doing this if you could ask whatsapp bot which could tell you insight of your order. Much simpler isn’t’ it.
Now most of the SAP CAI developer started thinking oh! this guy is just talking about building a bot in SAP CAI and expose this bot thorough another channel. But here is trick there is no whatsapp channel available in SAP CAI just like messenger, alexa, slack etc. 
Then how this integration is possible?
This answer is also very simple its Twilio which will help us to achieve this.
What is Twilio?
Twilio is a cloud communications platform as a service. Twilio allows software developers to programmatically make and receive phone calls, send and receive text messages, and perform other communication functions using its web service APIs
Discussing  about twilio more  won’t make sense here because people are smart enough to googling and do r&d on it. But what most important thing i am going to discuss is how twilio enabling this integration.
Lets look at the technical architecture

Business Story
Bestrun is a US based company who use S/4HANA to run their business. Brooke is newly on-boarded employee in Bestrun and she is eagerly waiting to get her new laptop to start work. As many employee joined in last seven days, Bestrun had to place an order for Brooke which take approximate two day to deliver the order. Other side Brooke is quite excited like others new employee to start working, so she is always wondering when she will get the laptop. In the meantime she remembered her on boarding training  where she was introduced to Sarah a Whatsapp bot who can help employee to know different Business insight and information as Sarah is integrated with their core system S/4HANA. So Brooke add her in whatsapp account and ask about her order status and Sarah checked the order status in S/4HANA and  reply that order is delivered and you can see the smile on her face :-).


Enough of story let’s get into main business which is how we are going to connect the dots. Lets break this integration into smaller pieces so that it would make more easier to understand.
1. CDS and Odata service creation for querying order status. (In this example Purchase Requisition and Purchase order Status will be queried). Check this blog.
2. Exposing the odata service through cloud connector and creating proxy api using SAP Api management. Check this blog.
3. Designing the skill of chatbot in SAP Cai. Check this amazing tutorial
4. Creating  node.js app which will be interacting with S/4HANA and provide json response the way SAP CAI  understand. Check out my github repository.
5. Deploying the node.js app we created in last step into SAP Cloud Platform CF account.
6. Use the deployed application URL with proper path as webhook of skill in SAP CAI.
7. Test the bot using SAP CAI.
for 5, 6, 7 check my previous blog.
8. Create a free account in twilio.
9. Enable the whatsapp channel.
10. Create a twilio function to interact with SAP CAI using SAP CAI SDK.
11.Deploy the function and use function Url as Webhook of WhatsApp channel.

Among 11 step till 7 there are numerous blog people have written so i am not going to write the same stuff again rather provide you reference link  which you can use. Lets discuss on last four points one by one.
8. Create free account in twilio using this link, you can get free trial account where all the beta services are enabled. Registration process is quite straight forward.
9Enable the WhatsApp channel
Twilio provide WhatsApp Sandbox account, you have to setup the sandbox account in your mobile. The process is pretty straight forward. You have to add your sand box number in your WhatsApp and send the code (E.G join say-rays) as first message from your WhatsApp like below.
(log-in to your twilio account and click on programmable sms, you will find this option)
On successful connection you will get Message received like below.
Now leave it like this, we will come to this later. Now we have to create twilio function which will interact with SAP CAI using SAP CAI SDK.
10. Create a twilio function to interact with SAP CAI using SAP CAI SDK.
Now click on runtime in your twilio dashboard, you will find function (beta) option like below.
Now explore the function, you will find manage and configure option, first click on configure option we have to add npm module for SAP CAI SDK.

Now in dependency list we need to add SAP CAI npm module with correct version.
After saving this now go to manage function option and add function with blank template.
Now give a function name, path and add the below code and save it like below.

After pasting the below code and before saving replace the request token with your request token which is used in 4th line. You can get easily the request token from your bot like below.
Twilio Function code.
exports.handler = function(context, event, callback) {
global.twiml = new Twilio.twiml.MessagingResponse();
    var sapcai = require('sapcai')
    
 
 let build = new sapcai.build('a1c27748c4cf50844f134b8e0590d61c', 'en')
  build.dialog({ type: 'text', content: event.Body}, { conversationId: '918884211139' })
  .then(function(res) {
      'debugger';
    dta = res.messages[0].content;
    twiml.message(dta);
    callback(null, twiml);
  })
 
 //callback(null, twiml);
};

Now Save it, after successful save copy the function path which has to be Webhooked in WhatsApp channel.
11.Deploy the function and use function Url as Webhook of WhatsApp channel.
Now go to programmable sms and then go to WhatsApp Sandbox to add the function path as Webhook like below.
Save it and thats it. You can test it now.

Here i have attached a vedio of this Integration testing, hope everyone would like it.