Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
yes_sapteam
Participant

Usually, when talking about attachments, we are thinking of someone who have to choose the file he want to attach,

and for this there are numerous posts.

I want to talk about a scenario where I know where the file is and I want to attach it to the object without user input.

Specific, the scenario I was facing was like this:

  • The user enter t-code MIRO (Enter Incoming Invoice), fills data for new Invoice, and save.
  • Than the user enter t-code MIR4 (Display Invoice Document) with the newly created Invoice.
  • In the MIR4 PF-STATUS we added button (using Enhancement Points),
    which allow the user to scan the Invoice's hard-copy.
  • Behind the button there is a code we bought for about 1,000USD from this web-site http://www.minipps.com/default.aspx.
    This code activate the user's scanner, and scan the file to a preconfigured location on her/his PC.
  • Now, in my code I have to attach the scanned file from that known location.

Basically, I used 3 FMs:

  1. SO_OBJECT_UPLOAD
  2. SO_OBJECT_INSERT
  3. BINARY_RELATION_CREATE_COMMIT

  • For whatever unimaginable reason, I can't attach a file, or even paste the code properly, so forgive for this site's limitations :???:
  • Read the Notes at the end.

This is the FM which is called from the button:
FUNCTION z_invoice_wf_scan_to_sap.

*"----------------------------------------------------------------------

*"*"Local Interface:

*"  IMPORTING

*"     VALUE(IV_BELNR) TYPE  RE_BELNR

*"     VALUE(IV_GJAHR) TYPE  GJAHR

*"     REFERENCE(IV_OBJTYPE) TYPE  SWO_OBJTYP

*"----------------------------------------------------------------------

   DATA: lv_full_file_path   TYPE draw-filep.

   PERFORM scan_to_file

                    USING    iv_belnr

                    CHANGING lv_full_file_path.

   CHECK lv_full_file_path IS NOT INITIAL.

   PERFORM check_file_exist

                    CHANGING lv_full_file_path.

   CHECK lv_full_file_path IS NOT INITIAL.

   PERFORM attach_file

                    USING    iv_belnr

                             iv_gjahr

                             iv_objtype

                             lv_full_file_path.

   PERFORM delete_folder

                    USING    lv_full_file_path.

   PERFORM initiate_wf_event

                    USING    iv_belnr

                             iv_gjahr.

ENDFUNCTION.



And These are the Forms:

*----------------------------------------------------------------------*

*              Form  Check_File_Exist

*

* This function will if the scanned file exist.

* There is no way to tell if the user canceled the scanning from

* the results of the FMs and Methods under "Scan_File" form,

* so the only way to tell is check if the file exist.

*----------------------------------------------------------------------*

FORM check_file_exist

                 CHANGING cv_full_file_path   TYPE draw-filep.

   DATA: lv_file   TYPE string,

         lv_result  TYPE abap_bool,

         lv_subrc  TYPE string.

* Convert to Method type.

   lv_file = cv_full_file_path.

   CALL METHOD cl_gui_frontend_services=>file_exist

     EXPORTING

       file                 = lv_file

     RECEIVING

       result               = lv_result      "X=file exist

     EXCEPTIONS

       cntl_error           = 1

       error_no_gui         = 2

       wrong_parameter      = 3

       not_supported_by_gui = 4

       OTHERS               = 5.

* Error searching file.

   IF sy-subrc <> 0.

     CLEAR: cv_full_file_path.     "Indicate error.

     lv_subrc = sy-subrc.

     CONDENSE lv_subrc.

     MESSAGE i002(zmm_invoice_wf) WITH lv_subrc 'Checking File'(010).   "Error #& when calling "&" - please report.

   ENDIF.

* File does not exist.

   IF lv_result <> 'X'.

     CLEAR: cv_full_file_path.

     MESSAGE i004(zmm_invoice_wf).   "No documents scanned.

   ENDIF.

ENDFORM.                    "Check_File_Exist

*----------------------------------------------------------------------*

*              Form  Attach_File

*

* This function will attach the scanned Invoice to the Invoice object.

*----------------------------------------------------------------------*

FORM attach_file

             USING iv_belnr            TYPE re_belnr       "Ivoice number

                   iv_gjahr            TYPE gjahr          "Invoice year

                   iv_objtype          TYPE swo_objtyp     "Object type (BUS...)

                   iv_full_file_path   TYPE draw-filep.    "Scanned file full-path

   DATA: lt_objcont    TYPE STANDARD TABLE OF soli,

         ls_folder_id  TYPE sofdk,

         ls_obj_id     TYPE soodk,

         ls_object     TYPE borident,

         ls_obj_roleb  TYPE borident,

         lt_objhead    TYPE soli_tab,

         ls_hd_change  TYPE sood1.

   DATA: lv_subrc      TYPE string.

* Write UI message.

   zcl_messages=>display_message( 'Attaching Invoice...' )"#EC NOTEXT

   PERFORM prepare_before_object_insert

                                   USING    iv_full_file_path

                                   CHANGING ls_folder_id

                                            lt_objcont.

   PERFORM call_so_object_upload

                             USING    ls_folder_id

                                      iv_full_file_path

                             CHANGING lt_objcont

                                      lt_objhead

                                      ls_hd_change

                                      ls_obj_id.

   PERFORM call_so_object_insert

                             USING    ls_folder_id

                                      lt_objcont

                                      lt_objhead

                                      ls_hd_change

                                      iv_full_file_path

                             CHANGING ls_obj_id.

   ls_obj_roleb-objtype = 'MESSAGE'.

* Build Object-key.

   CONCATENATE ls_folder_id

               ls_obj_id-objtp

               ls_obj_id-objyr

               ls_obj_id-objno

         INTO ls_obj_roleb-objkey.

   CONCATENATE iv_belnr iv_gjahr INTO ls_object-objkey.

   ls_object-objtype = iv_objtype.

   CALL FUNCTION 'BINARY_RELATION_CREATE_COMMIT'

     EXPORTING

       obj_rolea      = ls_object

       obj_roleb      = ls_obj_roleb

       relationtype   = 'ATTA'

     EXCEPTIONS

       no_model       = 1

       internal_error = 2

       unknown        = 3

       error_message  = 4

       OTHERS         = 5.

   IF sy-subrc <> 0.

     lv_subrc = sy-subrc.

     CONDENSE lv_subrc.

     MESSAGE i002(zmm_invoice_wf) WITH lv_subrc 'Attach Object'(005).   "Error #& when calling "&" - please

   ENDIF.

ENDFORM.                    "Attach_File

*----------------------------------------------------------------------*

*              Form  Delete_Folder

*

* This function will delete the folder that was created for the scanned

* file so to avoid filling up users drive quota.

*----------------------------------------------------------------------*

FORM delete_folder

             USING iv_full_file_path   TYPE draw-filep.    "Scanned file full-path

   DATA: lv_from_file  TYPE rlgrap-filename,

         lv_drive      TYPE pcfile-drive,

         lv_path       TYPE rlgrap-filename,

         lv_path_str   TYPE string,

         lv_file_str   TYPE string,

         lv_cmd_param  TYPE string,

         lv_rc          TYPE i,

         lv_subrc      TYPE string.

* Convert to FM type.

   lv_from_file = iv_full_file_path.

   CALL FUNCTION 'Z_PC_SPLIT_COMPLETE_FILENAME'

     EXPORTING

       complete_filename       = lv_from_file

       path_separator          = '\'

     IMPORTING

       drive                   = lv_drive

       path                    = lv_path

     EXCEPTIONS

       invalid_drive           = 1

       invalid_extension       = 2

       invalid_name            = 3

       invalid_path            = 4

       separator_not_specified = 5

       OTHERS                  = 6.

   IF sy-subrc <> 0.

     lv_subrc = sy-subrc.

     CONDENSE lv_subrc.

     MESSAGE i002(zmm_invoice_wf) WITH lv_subrc 'Find Folder'(008).   "Error #& when calling "&" - please report.

     RETURN.

   ENDIF.

* Create Folder path.

   CONCATENATE lv_drive ':' lv_path INTO lv_path_str.

* Create "RMDIR" command string.

   CONCATENATE '"' lv_path_str '"' INTO lv_path_str.                           "Full path with quotes

   CONCATENATE 'rmdir /q /s' lv_path_str INTO lv_cmd_param SEPARATED BY ' '.   "RMDIR command with spaces

   CONCATENATE '/C' '"' lv_cmd_param '"' INTO lv_cmd_param SEPARATED BY ' '.

   CALL METHOD cl_gui_frontend_services=>execute

     EXPORTING

       application            = 'cmd'

       parameter              = lv_cmd_param

     EXCEPTIONS

       cntl_error             = 1

       error_no_gui           = 2

       bad_parameter          = 3

       file_not_found         = 4

       path_not_found         = 5

       file_extension_unknown = 6

       error_execute_failed   = 7

       synchronous_failed     = 8

       not_supported_by_gui   = 9

       OTHERS                 = 10.

   IF sy-subrc <> 0.

     lv_subrc = sy-subrc.

     CONDENSE lv_subrc.

     MESSAGE i002(zmm_invoice_wf) WITH lv_subrc 'Delete Folder'(011).   "Error #& when calling "&" - please report.

   ENDIF.

ENDFORM.                    "Delete_Folder

*----------------------------------------------------------------------*

*              Form  Initiate_WF_Event

*

* This function will initiate a Work-flow event.

*----------------------------------------------------------------------*

FORM initiate_wf_event

             USING iv_belnr            TYPE re_belnr       "Ivoice number

                   iv_gjahr            TYPE gjahr.         "Invoice year

   DATA: lv_object_key     TYPE swr_struct-object_key,

         lv_return_code    TYPE sy-subrc,

         lv_subrc          TYPE string.

* Build Object-key.

   CONCATENATE iv_belnr iv_gjahr INTO lv_object_key.

   CALL FUNCTION 'SAP_WAPI_CREATE_EVENT'

     EXPORTING

       object_type = 'BUS2081'

       object_key  = lv_object_key

       event       = 'startapproval'

       commit_work = 'X'

     IMPORTING

       return_code = lv_return_code.

   IF lv_return_code IS NOT INITIAL.

     lv_subrc = sy-subrc.

     CONDENSE lv_subrc.

     MESSAGE i002(zmm_invoice_wf) WITH lv_subrc 'Initiate WF'(012).   "Error #& when calling "&" - please report.

   ENDIF.

ENDFORM.                    "initiate_wf_event

*----------------------------------------------------------------------*

*              Form  Prepare_Before_Object_Insert

*

* This function will prepare data before calling "SO_OBJECT_INSERT".

*----------------------------------------------------------------------*

FORM prepare_before_object_insert

                             USING    iv_full_file_path   TYPE draw-filep     "Scanned file full-path

                             CHANGING cs_folder_id        TYPE sofdk

                                      ct_objcont          TYPE soli_tab.

   DATA: ls_objcont    TYPE soli.

   DATA: lv_subrc      TYPE string.

* Get Folder properties.

   CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET'

     EXPORTING

       region    = 'B'

     IMPORTING

       folder_id = cs_folder_id

     EXCEPTIONS

       OTHERS    = 0.

   IF sy-subrc <> 0.

     lv_subrc = sy-subrc.

     CONDENSE lv_subrc.

     MESSAGE i002(zmm_invoice_wf) WITH lv_subrc 'Folder ID'(003).   "Error #& when calling "&" - please report.

     RETURN.

   ENDIF.

   CONCATENATE '&KEY&' iv_full_file_path INTO ls_objcont-line.

   APPEND ls_objcont TO ct_objcont.

ENDFORM.                    "Prepare_Before_Object_Insert

*----------------------------------------------------------------------*

*              Form  Call_SO_OBJECT_UPLOAD

*

* This function will call FM "SO_OBJECT_INSERT".

*----------------------------------------------------------------------*

FORM call_so_object_upload

                         USING    is_folder_id        TYPE sofdk

                                  iv_full_file_path   TYPE draw-filep     "Scanned file full-path

                         CHANGING ct_objcont          TYPE soli_tab

                                  ct_objhead          TYPE soli_tab

                                  ls_hd_change        TYPE sood1

                                  cs_obj_id           TYPE soodk.

   DATA: ls_objhead           TYPE soli,

         lt_objcont           TYPE STANDARD TABLE OF soli.

   DATA: lv_type              TYPE rlgrap-filetype,   " VALUE 'BIN',

         lv_filelength        TYPE soxwd-doc_length,

         lv_cancelled         TYPE sonv-flag,

         lv_act_filetype      TYPE c,

         lv_act_filename      TYPE c,

         lv_act_objtype       TYPE soodk-objtp,

         lv_file_put_to_kpro  TYPE sonv-flag,

         lv_complete_filename TYPE rlgrap-filename,

         lv_extension         TYPE rlgrap-filename,

         lv_name              TYPE rlgrap-filename,

         lv_subrc             TYPE string.

   CALL FUNCTION 'SO_OBJECT_UPLOAD'

     EXPORTING

       filetype                = lv_type

       path_and_file           = iv_full_file_path

       no_dialog               = 'X'

     IMPORTING

       filelength              = lv_filelength

       f_cancelled             = lv_cancelled

       act_filetype            = lv_type

       act_filename            = lv_act_filename

       act_objtype             = lv_act_objtype

       file_put_to_kpro        = lv_file_put_to_kpro

     TABLES

       objcont                 = ct_objcont

     EXCEPTIONS

       file_read_error         = 1

      invalid_type            = 2

       x_error                 = 3

       object_type_not_allowed = 4

       kpro_insert_error       = 5

       error_message           = 6

       OTHERS                  = 7.

   IF sy-subrc <> 0.

     lv_subrc = sy-subrc.

     CONDENSE lv_subrc.

     MESSAGE i002(zmm_invoice_wf) WITH lv_subrc 'Object Upload'(006).   "Error #& when calling "&" - please report.

     RETURN.

   ENDIF.

* Convert to FM compatible.

   lv_complete_filename = iv_full_file_path.

   CALL FUNCTION 'Z_PC_SPLIT_COMPLETE_FILENAME'

     EXPORTING

       complete_filename       = lv_complete_filename

     IMPORTING

       extension               = lv_extension

       name                    = lv_name

     EXCEPTIONS

       invalid_drive           = 1

       invalid_extension       = 2

       invalid_name            = 3

       invalid_path            = 4

       separator_not_specified = 5

       OTHERS                  = 6.

   IF sy-subrc <> 0.

     lv_subrc = sy-subrc.

     CONDENSE lv_subrc.

     MESSAGE i002(zmm_invoice_wf) WITH lv_subrc 'File Details'(007).   "Error #& when calling "&" - please report.

     RETURN.

   ENDIF.

   ls_hd_change-objpri   = '5'.      "Priority: 5 out of 10

   ls_hd_change-objdes   = lv_name.

   ls_hd_change-file_ext = lv_extension.

   ls_hd_change-objlen   = lv_filelength.

   ls_hd_change-extct    = 'K'.    "lv_file_put_to_kpro.

   CONCATENATE '&SO_FILENAME=' lv_name '.' lv_extension INTO ls_objhead-line. "#EC NOTEXT

   APPEND ls_objhead TO ct_objhead.

   CLEAR: ls_objhead.

   CONCATENATE '&SO_FORMAT=' lv_type INTO ls_objhead-line.   "#EC NOTEXT

   APPEND ls_objhead TO ct_objhead.

ENDFORM.                    "Call_SO_OBJECT_UPLOAD

*----------------------------------------------------------------------*

*              Form  Call_SO_OBJECT_INSERT

*

* This function will call FM "SO_OBJECT_INSERT".

*----------------------------------------------------------------------*

FORM call_so_object_insert

                         USING    is_folder_id        TYPE sofdk

                                  it_objcont          TYPE soli_tab

                                  it_objhead          TYPE soli_tab

                                  is_hd_change        TYPE sood1

                                  iv_full_file_path   TYPE draw-filep     "Scanned file full-path

                         CHANGING cs_obj_id           TYPE soodk.

   DATA: lv_type       TYPE rlgrap-filetype,   " VALUE 'BIN',

         lv_subrc      TYPE string.

   CALL FUNCTION 'SO_OBJECT_INSERT'

     EXPORTING

       folder_id                  = is_folder_id

       object_type                = 'EXT'

       object_hd_change           = is_hd_change

       owner                      = sy-uname

     IMPORTING

       object_id                  = cs_obj_id

     TABLES

       objcont                    = it_objcont

       objhead                    = it_objhead

     EXCEPTIONS

       active_user_not_exist      = 1

       communication_failure      = 2

       component_not_available    = 3

       dl_name_exist              = 4

       folder_not_exist           = 5

       folder_no_authorization    = 6

       object_type_not_exist      = 7

       operation_no_authorization = 8

       owner_not_exist            = 9

       parameter_error            = 10

       substitute_not_active      = 11

       substitute_not_defined     = 12

       system_failure             = 13

       x_error                    = 14

       error_message              = 15

       OTHERS                     = 16.

   IF sy-subrc <> 0.

     lv_subrc = sy-subrc.

     CONDENSE lv_subrc.

     MESSAGE i002(zmm_invoice_wf) WITH lv_subrc 'Object Insert'(004).   "Error #& when calling "&" - please report.

     RETURN.

   ENDIF.

ENDFORM.                    "Call_SO_OBJECT_INSERT


Note:

  1. The code behind Form "scan_to_file" is the code we bought, so I didn't paste it here.
  2. I had to activate Work-flow after the scanning and attaching, so basically the call to FM "SAP_WAPI_CREATE_EVENT" is not relevant to the issue.
  3. I used my Z-FM "Z_PC_SPLIT_COMPLETE_FILENAME", but the original FM (PC_SPLIT_COMPLETE_FILENAME), or any other FM can be used.

I hope this will be useful.

Post any question and I'll do my best to help.

Enjoy,

Ayal Telem.

1 Comment