Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
sivaprasad_ml
Participant

Process scenario : In retail IT environment there are numerous systems integrated which has seamless communication to the SAP system. Since there are dependency of data which flows from third party systems continuously into SAP, this  needs to be validated to control the type of data making it completely error free while it is received or posted to SAP system.

Problem :

Goods Movement IDOC comes from host (NON SAP) which fails due to gap in reason code mapping between  host and SAP system.


  1. Correction :

The only way out to correct this problem is by identifying the data from the idocs which were failed and post them into SAP via MIGO transaction code manually..

   2. Bottleneck :

The frequency of failure occurrence depends upon the data flown to SAP as idocs from third party systems. If the data is so huge the rectification via manual posting becomes tedious to get these failure documents corrected and  posted through MIGO transaction. In a  normal scenario this would require three hours / day for performing this activity.


   3. Feasible solution :

A mechanism to be developed to post erratic data via a custom program in SAP for bulk uploading that could handle document creations in a single stretch. And thereby reducing human effort spent to achieve correction which is currently being done manually posting them one by one.

This requirement could be achieved by using the  BAPI_GOODSMVT_CREATE a standard BAPI provided by SAP in a custom developed program that could cater the necessity of uploading of data. The program shown below gets the file path, row begin and row end as inputs . Here in the figure 1.1 the local file path is set along with the row begin and column begin inputs. Generally in the source file the first row would be header so row begin would be 2 and end row we could consider as 5 and varies depends on the data that is to be processed.

Fig 1.1

After executing the program we get the log as shown in Fig 1.2 about the successful or unsuccessful updating.

Fig 1.2

Now lets see the core coding part of the program developed. This program has minimal procedural approach at the front end but has a class lying underneath which handles the major operations of the program such as loading the source file, preliminary checks, converting the source file to the desired format to make it ready for the uploading and finally posting the documents and getting the result for display through ALV output. We will see below step by step process involved in developing the component.

Step1. Create a structure ZST_GOODSMVT_UPL as shown in figure 1.3.

Fig 1.3.

Create the table types :

ZTT_GOODSMVT_ITEM for line type BAPI2017_GM_ITEM_CREATE

ZTT_BAPIRET2 for line type BAPIRET2,

ZTT_GOODSMVT_UPL for line type ZST_GOODSMVT_UPL.

Step 2. Create a class ZCL_GOODSMVT_UPLOAD with three methods as shown below.We will see each method and its parameters in detail.

Figure 1.4

Parameters for method MAP_FILE_PATH

Figure 1.5

Add the below code into this method. :

method map_file_path.

field-symbols : <ls_file> type file_table.

call method cl_gui_frontend_services=>file_open_dialog
exporting
window_title            = 'Choose File to be Uploaded'
default_extension       = '.xls'
changing
file_table              = e_filetab
rc                      = lv_rc
exceptions
file_open_dialog_failed = 1
cntl_error              = 2
error_no_gui            = 3
not_supported_by_gui    = 4
others                  = 5.

if sy-subrc <> 0.
  message e001(zgmupl).
else.
  read table e_filetab assigning <ls_file>  index 1.
  if sy-subrc eq 0.
   e_filename = <ls_file>-filename.
  endif.
endif.

  endmethod.


Parameters for method UPLOAD_FILE.

Figure 1.6


After creating the parameters the below code is added to the method.

method upload_file.

data : lt_file  type table of kcde_cells,
ls_final type zst_goodsmvt_upl,
lr_ex    type ref to cx_root,
lv_msg   type string.


field-symbols : <ls_file> type kcde_cells.

clear gt_final.
call function 'KCD_EXCEL_OLE_TO_INT_CONVERT'
exporting
filename                = i_filename
i_begin_col             = i_begcol
i_begin_row             = i_begrow
i_end_col               = i_endcol
i_end_row               = i_endrow
tables
intern                  = lt_file
exceptions
inconsistent_parameters = 1
upload_ole              = 2
others                  = 3.
if sy-subrc <> 0.
  message e002(zgmupl).
else.
  sort lt_file by row col.

endif.

clear : e_keyid , e_fldval .
loop at lt_file assigning <ls_file> .

try .
case <ls_file>-col.

when 1.
ls_final-keyid = <ls_file>-value.

when 2.
ls_final-budat = <ls_file>-value.

when 3.

ls_final-bldat = <ls_file>-value.

when 4.
ls_final-bktxt = <ls_file>-value.

when 5.
ls_final-matnr = <ls_file>-value.

when 6.
ls_final-plant = <ls_file>-value.

when 7.
ls_final-lgort = <ls_file>-value.

when 8.
ls_final-bwart = <ls_file>-value.

  when 9.
ls_final-erfmg = <ls_file>-value.

when 10.
ls_final-erfme = <ls_file>-value.

when 11.
ls_final-sgtxt = <ls_file>-value.

when others.
endcase.

catch cx_root into lr_ex.

e_keyid = ls_final-keyid.
e_fldval = <ls_file>-value.
e_exmsg = lr_ex->get_text( ).

return.

endtry.

if <ls_file>-col = i_endcol.
append ls_final to gt_final.
clear ls_final.
continue.
endif.
endloop.

endmethod.


Parameters for method POST_GOODSMVT_UPLOAD.



Create the below code into the above method.

method post_goods_mvt.

call function 'BAPI_GOODSMVT_CREATE'
exporting
goodsmvt_header               = i_header
goodsmvt_code                 = i_code
TESTRUN                       = ' '
IMPORTING
GOODSMVT_HEADRET              e_headret
MATERIALDOCUMENT              e_matdoc
MATDOCUMENTYEAR               e_docyr
  tables
goodsmvt_item                 = i_item
return                        = e_return
.

if sy-subrc eq 0.

endif.

endmethod.

Now that we have created the parameters and methods, we have to create a main program to instantiate and use this class for our purpose.

Create a program ZMM_GOODSMVT_UPLOAD .

Create a top include ZMM_GOODSMVT_UPLOAD_TOP which has the global declarations.

TYPES : BEGIN OF ty_final.
INCLUDE STRUCTURE zst_goodsmvt_upl.
TYPES : END OF ty_final.


TYPES: BEGIN OF ty_log ,
keyid TYPE char10,
message TYPE bapi_msg,
END OF ty_log.


DATA : go_goodsmvt  TYPE REF TO zcl_goodsmvt_upload,
gt_filetab TYPE filetable,
gt_final TYPE TABLE OF ty_final,
gs_final TYPE ty_final,
  gt_log TYPE TABLE OF ty_log,
gs_log TYPE ty_log.

DATA : gv_file TYPE rlgrap-filename. " file name

DATA :    gs_header  TYPE bapi2017_gm_head_01,
gv_code    TYPE char2,
gt_item    TYPE TABLE OF bapi2017_gm_item_create,
gs_item    TYPE bapi2017_gm_item_create,
gs_headret TYPE bapi2017_gm_head_ret,
gv_matdoc  TYPE bapi2017_gm_head_ret-mat_doc,
gv_docyr   TYPE bapi2017_gm_head_ret-doc_year,
gt_return  TYPE TABLE OF bapiret2.

CONSTANTS : gc_code TYPE char2 VALUE '03'.

FIELD-SYMBOLS : <gs_return> TYPE bapiret2,
<gs_final> TYPE zst_goodsmvt_upl.


PARAMETERS : sp_file   TYPE rlgrap-filename,
sp_brow   TYPE i,
sp_bcol   TYPE i DEFAULT '1' NO-DISPLAY,
sp_erow   TYPE i,
sp_ecol   TYPE i DEFAULT '11' NO-DISPLAY.

Create another include ZMM_GOODSMVT_UPLOAD_F01.  which handles the required routines.

First we will have a look at the main program

and the subsequent performs we see in it are created in the include ZMM_GOODSMVT_UPLOAD_F01.

REPORT  zmm_goodsmvt_upload.

INCLUDE zmm_goodsmvt_upload_top.
INCLUDE zmm_goodsmvt_upload_f01.

INITIALIZATION.

AT SELECTION-SCREEN.
*--validate the max row count
PERFORM validate_rows.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR sp_file.

CLEAR : gt_filetab,
gt_final.

CREATE OBJECT go_goodsmvt.

*--Map the file path
CALL METHOD go_goodsmvt->map_file_path
IMPORTING
e_filetab  = gt_filetab
e_filename = sp_file.

START-OF-SELECTION.
*--Upload the data from source file
PERFORM upload_data.
*--Display the output log
PERFORM display_output.

We will closely view each performs and the process they are assigned to carry out in the below .


Fig 1.8


For  PERFORM upload_data create the below code.

FORM upload_data .

DATA : lv_msg   TYPE char100,
lv_keyid TYPE char10,
lv_fldval TYPE char25,
lv_exmsg TYPE string.

CLEAR : gv_file, lv_keyid, lv_fldval, lv_exmsg.
gv_file = sp_file.

CREATE OBJECT go_goodsmvt.
*--Get the table values
CALL METHOD go_goodsmvt->upload_file
EXPORTING
i_filename = gv_file
i_begrow   = sp_brow
i_begcol   = sp_bcol
i_endrow   = sp_erow
i_endcol   = sp_ecol
IMPORTING
e_keyid    = lv_keyid
e_fldval   = lv_fldval
e_exmsg    = lv_exmsg
gt_final   = gt_final.
*--check for error
IF NOT lv_keyid IS INITIAL.

CLEAR lv_msg.
CONCATENATE text-011 lv_keyid text-012 lv_fldval lv_exmsg INTO
lv_msg SEPARATED BY space.
MESSAGE lv_msg TYPE 'S' DISPLAY LIKE 'E'.
RETURN.

ELSEIF  gt_final IS INITIAL.
*-- if no data found to be uploaded
MESSAGE text-009 TYPE 'S' DISPLAY LIKE 'E'.
RETURN.

ENDIF.

*--prepare for posting.
LOOP AT gt_final ASSIGNING <gs_final>.

CLEAR : gs_header, gs_headret, gv_matdoc,
gv_docyr, gt_return, gs_item.
*--Populate header
CALL FUNCTION 'CONVERT_DATE_TO_INTERNAL'
EXPORTING
date_external            = <gs_final>-budat
IMPORTING
date_internal            = gs_header-pstng_date
EXCEPTIONS
date_external_is_invalid = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.

CALL FUNCTION 'CONVERT_DATE_TO_INTERNAL'
EXPORTING
date_external            = <gs_final>-bldat
IMPORTING
date_internal            = gs_header-doc_date
EXCEPTIONS
date_external_is_invalid = 1
OTHERS                   = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.

gs_header-header_txt = <gs_final>-bktxt.

*--Populate item
UNPACK <gs_final>-matnr TO gs_item-material.

gs_item-plant     = <gs_final>-plant.
gs_item-stge_loc  = <gs_final>-lgort.
gs_item-move_type = <gs_final>-bwart.
gs_item-entry_qnt = <gs_final>-erfmg.
gs_item-entry_uom = <gs_final>-erfme.
gs_item-item_text = <gs_final>-sgtxt.

APPEND gs_item TO gt_item.
CLEAR gs_item.

AT END OF keyid.
*--call the BAPI to post the document
CALL METHOD go_goodsmvt->post_goods_mvt
EXPORTING
i_header  = gs_header
i_code    = gc_code
i_item    = gt_item
i_testrun = space
IMPORTING
e_headret = gs_headret
e_matdoc  = gv_matdoc
e_docyr   = gv_docyr
e_return  = gt_return.
*--of error in posting
IF NOT gt_return IS INITIAL.

LOOP AT gt_return ASSIGNING <gs_return>.
*--Prepare log
gs_log-keyid = <gs_final>-keyid.
CONCATENATE <gs_return>-type <gs_return>-id
<gs_return>-number <gs_return>-message
INTO gs_log-message SEPARATED BY space.
APPEND gs_log TO gt_log.
CLEAR gs_log.

ENDLOOP.

ELSE.
*--for successful posting
IF NOT gs_headret-mat_doc IS INITIAL.

*--commit work and wait. " for successful posting.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
*--Prepare log
gs_log-keyid = <gs_final>-keyid.
CONCATENATE text-003 gs_headret-mat_doc text-002
gs_headret-doc_year text-004 INTO gs_log-message
SEPARATED BY space.

APPEND gs_log TO gt_log.
CLEAR gs_log.
ENDIF.
ENDIF.
CLEAR : gs_header , gt_item, gs_headret,
gv_matdoc, gv_docyr, gt_return.

ENDAT.
ENDLOOP.
ENDFORM. " UPLOAD_DATA

For PERFORM display_output use the below code.

FORM display_output .
*
DATA: lo_alv        TYPE REF TO cl_salv_table,
lx_msg        TYPE REF TO cx_salv_msg,     
lo_layout     TYPE REF TO cl_salv_layout,
lv_functions  TYPE REF TO cl_salv_functions_list,
lv_column     TYPE REF TO cl_salv_column_list,
lv_columns    TYPE REF TO cl_salv_columns,
lo_aggrs      TYPE REF TO cl_salv_aggregations,    
lo_key_col    TYPE REF TO cl_salv_columns_table .
*
DATA: ls_key        TYPE salv_s_layout_key,
lf_variant    TYPE slis_vari.
*
CONSTANTS : lc_x    TYPE c VALUE 'X'.
*
IF NOT gt_log IS INITIAL.
*--Calling the factory method
TRY.
cl_salv_table=>factory(
IMPORTING
r_salv_table = lo_alv
CHANGING
t_table      = gt_log ).
CATCH cx_salv_msg INTO lx_msg.
EXIT.
ENDTRY.
lo_layout = lo_alv->get_layout( ).
*--set Layout save restriction
ls_key-report = sy-repid.
lo_layout->set_key( ls_key ).
lo_layout->set_save_restriction(           if_salv_c_layout=>restrict_none ).
*--set initial Layout
lf_variant = 'DEFAULT'.
lo_layout->set_initial_layout( lf_variant ).
*--activate ALV generic Functions
lv_functions = lo_alv->get_functions( ).
lv_functions->set_all( lc_x ).
lv_columns = lo_alv->get_columns( ).
lv_columns->set_optimize( lc_x ).
lo_aggrs = lo_alv->get_aggregations( ).
lo_key_col = lo_alv->get_columns( ).
lo_key_col->set_optimize( lc_x ).
lo_key_col->set_key_fixation( 'X' ).
*--visible columns
TRY.

lv_column ?= lv_columns->get_column( text-005 ).
lv_column->set_short_text( text-006 ).
lv_column->set_medium_text( text-006 ).
lv_column->set_long_text( text-006 ).

lv_column ?= lv_columns->get_column( text-007 ).
lv_column->set_short_text( text-008 ).
lv_column->set_medium_text( text-008 ).
lv_column->set_long_text( text-008 ).

CATCH cx_salv_not_found.
EXIT.
ENDTRY.
lo_alv->display( ).
ENDIF.
*
ENDFORM. " DISPLAY_LOG

These text elements are created

Fig 1.9

Selection texts created.

Figure 2.0


Source File format :


Key ID,

posting date

doc date,

header text,

Material,

plant,

storage,

Mov type,

entry qty,

UOM,

Item text

Maintain the source file as mentioned in the above format in the excel file. The first column Key ID serves as an identifier to combine the line items into a single document.

Scalability :

Though this class has been created specifically to cater the goods adjustment upload, this could  be further enhanced by adding appropriate new fields to the structure , adding new methods to take it into a complete object oriented pattern design and can be used for  uploading data related to goods movement.






.

2 Comments