Thursday, February 13, 2020

Multilevel Workflow for Sales order change [VA02] In SAP ABAP.


Multilevel Workflow for Sales order change [VA02]

    For this type of workflow first we have to find out maximum level for the approval.
    For this we have to create activity.

 



Here we have to mention class name and its method as well as if it required then you to create some variable at container tab for import or export parameter.


Above binding is inside the task now below binding is outside the task.


Class method for finding maximum level for approver.


Method for get maximum level of approver
METHOD get_maxlevel.
  
DATA:ls_max_level TYPE zwf_dyn_vbak-zalevel.
  
DATA:lv_inita TYPE uname.

  lv_inita 
=  wfinitiator+2(12).

  
IF zterm 'X'.
    
SELECT MAXzalevel )
     
FROM zwf_dyn_vbak
     
INTO ls_max_level
     
WHERE approveby lv_inita AND field_name 'ZTERM'.
    max_level 
ls_max_level.
  
ENDIF.

  
IF kvgr2 'X'.
    
SELECT MAXzalevel )
      
FROM zwf_dyn_vbak
      
INTO ls_max_level
      
WHERE approveby lv_inita AND field_name 'AVGR2'.
    max_level 
ls_max_level.

  
ENDIF.
ENDMETHOD.


Next activity is we have to generate loop step in workflow.





After getting maximum level for approver next we have to create an instance for generate link for sales order in email. Below screen for instance binding inside the task.


Next screen is outside binding after task is created.


Now in loop we have to increment the counter using custom container.







Code for Email ID with Approver level:
METHOD get_emailid.

  
DATAis_wf_vbak TYPE zwf_dyn_vbak,
        is_addsmtp 
TYPE bapiadsmtp.

  
DATA lv_inita TYPE uname,
         lv_add 
TYPE bapiaddr3.
  
DATA return TYPE bapiret2.

  lv_inita 
wfinitiator+2(12).
  
IF zterm 'X'.
    
SELECT SINGLE *
    
FROM zwf_dyn_vbak
    
INTO is_wf_vbak
   
WHERE approveby lv_inita AND zalevel apprv_level AND             field_name 'ZTERM'.

    
IF sy-subrc 0.
      email_app 
is_wf_vbak-a_emailid.
      email_init 
is_wf_vbak-i_emailid.
    
ENDIF.
  
ENDIF.

  IF kvgr2 'X'.
    
SELECT SINGLE *
    
FROM zwf_dyn_vbak
    
INTO is_wf_vbak
   
WHERE approveby lv_inita AND zalevel apprv_level AND             field_name 'AVGR2'.

    
IF sy-subrc 0.
      email_app 
is_wf_vbak-a_emailid.
      email_init 
is_wf_vbak-i_emailid.
    
ENDIF.
  
ENDIF.
ENDMETHOD.


Now next activity is user decision for whether user has approve or not sales order.
In this user decision we have to create rule. After this we have to set flag whether it is approved or reject. If user has reject the sales order then we have to set loop level with max level.
Next screen for set flag for approve.


Below screen is for set flag for rejection.


After Reject flag set then set the loop level and max level same.


After the approve or reject process we have to check the flag if it is approve or reject.






Binding for approve sales order.



Code for set billing block as well as for approve and reject sales order.



method SET_BILLING_BLOCK.

  
DATA:ls_tvfst TYPE tvfst.

  
IF zterm 'X'.
  
SELECT SINGLE faksp vtext
    
FROM tvfst
    
INTO CORRESPONDING FIELDS OF ls_tvfst
    
WHERE faksp '41' AND spras 'EN'.

  
UPDATE vbak
    
SET faksk ls_tvfst-faksp
    
WHERE vbeln vbeln.
ENDIF.

IF kvgr2 'X'.
  
SELECT SINGLE faksp vtext
    
FROM tvfst
    
INTO CORRESPONDING FIELDS OF ls_tvfst
    
WHERE faksp '41' AND spras 'EN'.

  
UPDATE vbak
    
SET faksk ls_tvfst-faksp
    
WHERE vbeln vbeln.
ENDIF.
endmethod.


Method for approve sales order

method APPROVE_SALES_ORDER.
  
IF zterm 'X'.
    
UPDATE vbak
      
SET zzterm1 ' '
      
where vbeln vbeln.
  
ENDIF.

  
IF kvgr2 'X'.
    
UPDATE vbak
      
SET zzkvgr2 ' '
      
where vbeln vbeln.
  
ENDIF.
endmethod.

Method for Reject sales order with attachment file for reject reason.

METHOD reject_sales_order.
  
IF zterm 'X' OR kvgr2 'X'.
    
DATA lv_docid TYPE so_entryid,
           lv_docid_tmp 
TYPE char90,
           lt_attach 
TYPE STANDARD TABLE OF swr_object.

    
DATA ls_attach TYPE swr_object.
    
DATA flag TYPE flag.

    
FIELD-SYMBOLS <ls_rejtext> TYPE solisti1.

    
CALL FUNCTION 'SAP_WAPI_GET_ATTACHMENTS'
      
EXPORTING
        workitem_id 
im_wiid
      
TABLES
        attachments 
lt_attach.

    
IF NOT lt_attach[] IS INITIAL.
      
READ TABLE lt_attach INTO ls_attach INDEX 1.
      
IF sy-subrc EQ 0.
        
REPLACE ALL OCCURRENCES OF 'SOFM' IN ls_attach-object_id WITH space.
        
SHIFT ls_attach-object_id LEFT DELETING LEADING space.
*      CONDENSE LV_DOCID NO-GAPS.
        lv_docid_tmp 
ls_attach-object_id.
*      CONDENSE LV_DOCID_TMP NO-GAPS.
        lv_docid 
lv_docid_tmp.
      
ENDIF.
    
ENDIF.
***FM to  get content text for Dicument key
    
CALL FUNCTION 'SO_DOCUMENT_READ_API1'
      
EXPORTING
        document_id                
lv_docid
      
TABLES
        object_content             
text
      
EXCEPTIONS
        document_id_not_exist      
1
        operation_no_authorization 
2
        x_error                    
3
        
OTHERS                     4.
    
IF sy-subrc <> 0.
* Implement suitable error handling here
    
ELSE.
      
DELETE text WHERE line+0(3) = '000'.
      
LOOP AT text ASSIGNING <ls_rejtext>.
        <ls_rejtext>+0
(3) = ' '.
      
ENDLOOP.
    
ENDIF.
  
ENDIF.
ENDMETHOD.



After approve from all level we have to remove the billing block.


method UPDATE_VBAK.
DATA:ls_vbak TYPE vbak.

  
SELECT SINGLE *
    
FROM vbak
    
INTO ls_vbak
    
WHERE vbeln vbeln.

    
IF ls_vbak-zzterm1 ' ' and ls_vbak-zzkvgr2 ' '.
      
UPDATE vbak
        
SET faksk ' '
        
where vbeln =  vbeln.
    
ENDIF.
endmethod.





Total and Subtotal Report Example in SAP ABAP.


Total and Subtotal Program Example in SAP ABAP.



REPORT  ZREPORTS_TOTAL.

TABLES: ekko.
TYPE-POOLS: slis.
DATA: wa_fcat   TYPE lvc_s_fcat,
      it_fcat   TYPE lvc_t_fcat,
      wa_layout TYPE lvc_s_layo,
      wa_top    TYPE slis_listheader,
      it_top    TYPE slis_t_listheader.

TYPES: BEGIN OF ty_ekko,
ebeln TYPE ekko-ebeln,
aedat TYPE ekko-aedat,
END OF ty_ekko.
DATA: wa_ekko TYPE ty_ekko,
      it_ekko TYPE TABLE OF ty_ekko.

TYPES: BEGIN OF ty_ekpo,
ebeln TYPE ekpo-ebeln,
ebelp TYPE ekpo-ebelp,
matnr TYPE ekpo-matnr,
werks TYPE ekpo-werks,
menge TYPE ekpo-menge,
meins TYPE ekpo-meins,
END OF ty_ekpo.
DATA: wa_ekpo TYPE ty_ekpo,
      it_ekpo TYPE TABLE OF ty_ekpo.

TYPES: BEGIN OF ty_out,
ebeln TYPE char15,
ebelp TYPE char5,
matnr TYPE ekpo-matnr,
werks TYPE ekpo-werks,
menge TYPE ekpo-menge,
meins TYPE ekpo-meins,
color TYPE char4,
bold  TYPE lvc_t_styl,
END OF ty_out.
DATA: wa_out TYPE ty_out,
      it_out TYPE TABLE OF ty_out.

INITIALIZATION.
SELECT-OPTIONS s_aedat FOR ekko-aedat.

START-OF-SELECTION.
PERFORM get_ekko.
PERFORM get_ekpo.

END-OF-SELECTION.
PERFORM prepare_output.
PERFORM field_catalog.
PERFORM alv_grid_display.

TOP-OF-PAGE.
PERFORM top_of_page.
*&---------------------------------------------------------------------*
*&      Form  GET_EKKO
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM get_ekko .

SELECT ebeln aedat FROM ekko
INTO TABLE it_ekko
WHERE aedat IN s_aedat.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  GET_EKPO
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM get_ekpo .

IF it_ekko IS NOT INITIAL.
SELECT ebeln ebelp matnr werks menge meins
FROM ekpo INTO TABLE it_ekpo
FOR ALL ENTRIES IN it_ekko
WHERE ebeln = it_ekko-ebeln
AND matnr NE ' '.

IF sy-subrc = 0.
SORT it_ekpo BY ebeln ebelp.
ENDIF.
ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  PREPARE_OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM prepare_output .

DATA: lw_bold TYPE lvc_s_styl,
      lt_bold TYPE lvc_t_styl.

IF it_ekpo IS NOT INITIAL.
LOOP AT it_ekpo INTO wa_ekpo.
wa_out-ebeln = wa_ekpo-ebeln.
wa_out-ebelp = wa_ekpo-ebelp.
wa_out-matnr = wa_ekpo-matnr.
SHIFT wa_out-matnr LEFT DELETING LEADING '0'.
wa_out-werks = wa_ekpo-werks.
wa_out-menge = wa_ekpo-menge.
wa_out-meins = wa_ekpo-meins.
APPEND wa_out TO it_out.
CLEAR: wa_out.

AT END OF ebeln.
SUM.
wa_out-ebeln = 'SUB TOTAL'.
wa_out-menge = wa_ekpo-menge.
wa_out-color = 'C200'.
lw_bold-style = '00000121'.
INSERT lw_bold INTO lt_bold INDEX 1.
wa_out-bold = lt_bold.
FREE lt_bold.

APPEND wa_out TO it_out.
CLEAR: wa_out, lw_bold, wa_ekpo.
ENDAT.

AT LAST.
SUM.
wa_out-ebeln = 'GRAND TOTAL'.
wa_out-menge = wa_ekpo-menge.
wa_out-color = 'C210'.
lw_bold-style = '00000121'.
INSERT lw_bold INTO lt_bold INDEX 1.
wa_out-bold = lt_bold.
FREE lt_bold.

APPEND wa_out TO it_out.
CLEAR: wa_out, lw_bold, wa_ekpo.
ENDAT.
ENDLOOP.
ENDIF.

FREE it_ekpo.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  FIELD_CATALOG
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM field_catalog .

DATA: lv_col TYPE i VALUE 0.

lv_col            = 1 + lv_col.
wa_fcat-col_pos   = lv_col.
wa_fcat-fieldname = 'EBELN'.
wa_fcat-reptext   = 'Purchase Order'.
APPEND wa_fcat TO it_fcat.
CLEAR wa_fcat.

lv_col            = 1 + lv_col.
wa_fcat-col_pos   = lv_col.
wa_fcat-fieldname = 'EBELP'.
wa_fcat-reptext   = 'Item'.
APPEND wa_fcat TO it_fcat.
CLEAR wa_fcat.

lv_col            = 1 + lv_col.
wa_fcat-col_pos   = lv_col.
wa_fcat-fieldname = 'MATNR'.
wa_fcat-reptext   = 'Material'.
APPEND wa_fcat TO it_fcat.
CLEAR wa_fcat.

lv_col            = 1 + lv_col.
wa_fcat-col_pos   = lv_col.
wa_fcat-fieldname = 'WERKS'.
wa_fcat-reptext   = 'Plant'.
APPEND wa_fcat TO it_fcat.
CLEAR wa_fcat.

lv_col            = 1 + lv_col.
wa_fcat-col_pos   = lv_col.
wa_fcat-fieldname = 'MENGE'.
wa_fcat-reptext   = 'Quantity'.
APPEND wa_fcat TO it_fcat.
CLEAR wa_fcat.

lv_col            = 1 + lv_col.
wa_fcat-col_pos   = lv_col.
wa_fcat-fieldname = 'MEINS'.
wa_fcat-reptext   = 'Unit'.
APPEND wa_fcat TO it_fcat.
CLEAR wa_fcat.

wa_layout-zebra      = 'X'.
wa_layout-cwidth_opt = 'X'.
wa_layout-info_fname = 'COLOR'.
wa_layout-stylefname = 'BOLD'.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  ALV_GRID_DISPLAY
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM alv_grid_display .

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
  i_callback_program     = sy-repid
  i_callback_top_of_page = 'TOP_OF_PAGE'
  is_layout_lvc          = wa_layout
  it_fieldcat_lvc        = it_fcat
TABLES
  t_outtab               = it_out
EXCEPTIONS
  program_error          = 1
  OTHERS                 = 2.


ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  TOP_OF_PAGE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM top_of_page .

REFRESH it_top.

wa_top-typ  = 'H'.
wa_top-info = 'Purchasing List'.
APPEND wa_top TO it_top.
CLEAR wa_top.

CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
EXPORTING
  it_list_commentary = it_top.

ENDFORM.

ODATA Service UPDATE, DELETE & MODIFY Example in SAP ABAP.


Details about How to  record into table using GET_ENTITY method in OData service.
Table: SCARR
Step 1: Go to the T-Code: SEGW → Create New ODATA Object



Step 2: Created Project will appear Data model → Import → DDIC structure.



Provide the Entity name and Structure name and select the fields you want to use in oData service. At least one field of Entity should be Key field, selecting CARRID here as Key and click on Finish.





 Step 3: Project is created successfully after that click on below marked button to Generate Run time Artifacts.


 Step 4: After You’ll get following Success message after Generate Run time Artifacts.


 Step 5:After that go to Data Provider Extension (DPC_EXT) Class → Double click on DPC_EXT class ZCL_ZMTEST5_UMD_DPC_EXT.


 Step 6: After that go to GET_ENTITY method SCARRSET_GET_ENTITY → Click on the  Redefine button to Redefine GET_ENTITY method. After you  implementing this method to fetch records so that Updated / Modified & Deleted records can be validate.



 Code in GET_ENTITY  Example:

FIELD-SYMBOLS <fs_keytab> TYPE /iwbep/s_mgw_name_value_pair.
 Table IT_KEY_TAB contains the Input value from Frontend & through
ER_ENTITY parameter we can send the records back to Frontend.
UNASSIGN <fs_keytab>.
READ TABLE it_key_tab ASSIGNING <fs_keytab> INDEX 1.
  IF sysubrc IS INITIAL.
    SELECT SINGLE 
      FROM scarr
      INTO CORRESPONDING FIELDS OF er_entity
      WHERE carrid EQ <fs_keytab>value.
    UNASSIGN <fs_keytab>.
  ENDIF.

 Step 7: After that go to  UPDATE_ENTITY method SCARRSET_UPDATE_ENTITY → Click on Redefine button to Redefine UPDATE_ENTITY method.



Code in UPDATE_ENTITY method.

DATA TYPE zcl_zmtest5_umd_mpc=>.
* Capture input value from Frontend into workarea WA_SCARR
  CLEAR wa_scarr.
  io_data_provider->read_entry_dataIMPORTING es_data wa_scarr ).
* Here we can use UPDATE or MODIFY depending on the requirement 
  UPDATE scarr SET carrname wa_scarrcarrname
              url      wa_scarrurl
             WHERE carrid   wa_scarrcarrid.
  IF sysubrc IS INITIAL.
    COMMIT WORK.
  ENDIF.

 Step 8: Place the cursor on DELETE_ENTITY method SCARRSET_DELETE_ENTITY → Click on Redefine button to Redefine DELETE_ENTITY method.

Write below code in DELETE_ENTITY method:
FIELD-SYMBOLS <fs_keytab> TYPE /iwbep/s_mgw_name_value_pair.
* Parameter IT_KEY_TAB holds the input record from Frontend
  UNASSIGN <fs_keytab>.
  READ TABLE it_key_tab ASSIGNING <fs_keytab> INDEX 1.
  IF sysubrc IS INITIAL.
    DELETE FROM scarr WHERE carrid EQ <fs_keytab>value.
    IF sysubrc IS INITIAL.
      COMMIT WORK.
    ENDIF.
    UNASSIGN <fs_keytab>.
  ENDIF.

 Step 9Now add the Service in T Code: /IWFND/MAINT_SERVICE. Please give a look to my previous post oData service which consumes RFC about how to add a service. You can find the Service name in Run time Artifacts. Here service name is: ZMTEST5_UMD_SRV.



 Step 10: After adding the Service,  to test the Service Goto T Code: /IWFND/GW_CLIENT, You’ll get the below screen:

Select the Click on EntitySets and select your entity

 Filtering Record with CARRID = ‘ZZ’. Add filter in URL: /sap/opu/odata/sap/ZMTEST5_UMD_SRV/SCARRSet(Carrid=’ZZ’)

After executing record with CARRID = ‘ZZ’ will be displayed as:

 Step 11: Testing UPDATE functionality: Click on Use as Request button to copy the HTTP Response contents to HTTP Request, which works as Input.






Status code is 204, means executed successfully.




 Table has been updated.


 Step 12: Testing DELETE functionality: Select DELETE Radiobutton → provide the filter in URL → Execute.


 Record with CARRID = ‘ZZ’ has been deleted from SCARR table.


 Step 13: Display custom messages after Database operations. 

Deleting record from Table SCARR with CARRID = ‘ZX’. 

 Below code to display custom messages:

      DATA:ls_header TYPE ihttpnvp.
      ls_headername  ‘Custom Message’.
      ls_headervalue ‘{msg_typ:S, desc:Record deleted  }’.
      /iwbep/if_mgw_conv_srv_runtime~set_headerls_header ).

 If you deleting the record with CARRID = ‘ZX’ you are getting custom message:




Hierarchical ALV in SAP ABAP Example.


How to display a hierarchical sequential list ALV in SAP ABAP.
 TYPES: BEGIN OF ty_swa,
                  expand,
                  carrid TYPE s_carr_id,
                  carrname TYPE s_carrname,
             END OF ty_swa.
TYPES: BEGIN OF ty_swad,
                     carrid TYPE s_carr_id,
                     connid TYPE s_conn_id,
                     countryfr TYPE land1,
                     countryto TYPE land1,
              END OF ty_swad.
DATA: lt_swa TYPE TABLE OF ty_swa.
DATA: lt_swad TYPE TABLE OF ty_swad.
DATA: ls_layt TYPE slis_layout_alv.
DATA: lt_fcat TYPE slis_t_fieldcat_alv.
DATA: ls_fcat TYPE LINE OF slis_t_fieldcat_alv.
DATA: ls_key TYPE slis_keyinfo_alv.
START-OF-SELECTION.

SELECT carrid carrname
FROM scarr
INTO CORRESPONDING FIELDS OF TABLE lt_swa.

CHECK lt_swa[] IS NOT INITIAL.

SELECT carrid connidcountryfr countryto FROM spfli
INTO CORRESPONDING FIELDS OF TABLE lt_swad
FOR ALL ENTRIES IN lt_swa
 WHERE carrid = lt_swa-carrid.

”Layout 
ls_layt-expand_fieldname = ‘EXPAND’.
ls_layt-colwidth_optimize = ‘X’.
”Keyinfo 
ls_key-header01 = ‘CARRID’.
ls_key-item01 = ‘CARRID’.
“Build Fieldcat
ls_fcat-col_pos = ‘1’.
ls_fcat-fieldname = ‘CARRID’.
ls_fcat-tabname = ‘LT_SWA’.
ls_fcat-key = ‘X’.
ls_fcat-seltext_m = ‘Flight ID’.
APPEND ls_fcat TO lt_fcat.
CLEAR ls_fcat.
ls_fcat-col_pos = ‘2’.
ls_fcat-fieldname = ‘CARRNAME’.
ls_fcat-tabname = ‘LT_SWA’.
ls_fcat-seltext_m = ‘Flight Conn’.
APPEND ls_fcat TO lt_fcat.
CLEAR ls_fcat.
ls_fcat-col_pos = ‘3’.
ls_fcat-fieldname = ‘CONNID’.
ls_fcat-tabname = ‘LT_SWAD’.
ls_fcat-seltext_m = ‘Conn Number’.
APPEND ls_fcat TO lt_fcat.
CLEAR ls_fcat.
ls_fcat-col_pos = ‘4’.
ls_fcat-fieldname = ‘COUNTRYFR’.
ls_fcat-tabname = ‘LT_SWAD’.
ls_fcat-seltext_m = ‘From Country’.
APPEND ls_fcat TO lt_fcat.
CLEAR ls_fcat.
ls_fcat-col_pos = ‘5’.
ls_fcat-fieldname = ‘COUNTRYTO’.
ls_fcat-tabname = ‘LT_SWAD’.
ls_fcat-seltext_m = ‘To Country’.
APPEND ls_fcat TO lt_fcat.
CLEAR ls_fcat.
CALL FUNCTION ‘REUSE_ALV_HIERSEQ_LIST_DISPLAY’
EXPORTING
i_callback_program = sy-repid
is_layout = ls_layt
it_fieldcat = lt_fcat
i_tabname_header = ‘LT_SWA’
i_tabname_item = ‘LT_SWAD’
is_keyinfo = ls_key
TABLES
t_outtab_header = lt_SWA
t_outtab_item = lt_SWAD
EXCEPTIONS
program_error = 1
OTHERS = 2.