Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
VijayCR
Active Contributor
3,621
Hello all,

There could multiple scenarios in real time where we need to handle an inbound incoming email with attachments  and perform an action for example creation of a Business partner and attach the attachment in business partner or creation of a workflow in receiving the incoming PDF and attach the same in the workflows.

Interactive Offline Forms – Inbound Email Scenario

For this we should adapt to creation of the interactive offline forms


Interactive Adobe Forms Offline Scenario


This scenario offers a lot of advantages for the external user:

  • No SAP system access needed

  • External user most likely already knows PDF and has Adobe Reader, so no training time is required.

  • Static value help, static checking, simple arithmetic calculations


External user can save locally what he sent to SAP, print it, archive it etc.

For SAP Developer, there are also numerous advantages:

  • SAP Developer don’t need an application to embed the form, so no additional servers are required;

  • SAP Developer don’t need to re-enter data sent via paper or mail.


We can design the interactive adobe form using the below interactive components

Design – Email, Print, Reset Button, Input Button

Email Button


Out of the box Email sending functionality is available in adobe forms to send an email to the email defined in the shown settings.

The PDF attachment is automatically sent on use of this button

There is also option to define the subject for the email

However there are certain limitations that email body text and dynamic variables cannot be defined in this.

Print Form Button can be used to print the form

Reset button will clear all the fillable entries in the form

Preparing Form Template Call in Application Program

  • Call the function module FP_JOB_OPEN.

  • Use the parameters ( IE_OUTPUTPARAMS) of the structure SFPOUTPUTPARAMS to make settings for the form output. For example, specify whether you want the form to be printed, archived, or returned to the application program.

  • Special feature for interactive offline forms: To have the created form returned to you to be forwarded to Business Communication Services for sending by e-mail, set the parameter GETPDF.

  • To determine the name of the generated function module, call the function module FP_FUNCTION_MODULE_NAME.

  • Call the generated function module and send the parameters to the form interface. For example, set the language of the form in the import parameters. Special feature for interactive offline forms: Set the parameter FILLABLE to ‘X’ for Interactive scenario and ’F’  Offline Interactive forms

  • To cancel form processing, call function module FP_JOB_CLOSE.



Calling a template



Interactive Offline form


Interactive Offline Forms – Inbound Email Scenario

A classical Offline Customer creation scenario is considered for the interactive form creation

  • A Interactive PDF is sent to a recipient via E-Mail or downloaded from a website

  • Downloaded and filled locally without any connection to the backend SAP system

  • Sent back to the SAP system afterwards either via E-Mail, file upload or by calling a web Service

  • Evaluated in the backend and the data updated to the SAP system.


The new offline forms data processing infrastructure offers out of the box support for processing form data sent back via emails by:

  •  Handling PDFs through inbound mail handlers

  • Retrieving the form template information

  • Extraction of XML based form data from the PDF Form


Mail Input :

  • Mail Inbound Processing identifies the PDF attachments which need to be sent to the FP Inbound handler

  • Forms Processing inbound Handler is the defined generic handler which marshals the extraction of the data from the PDF and calls the correct application handler

  • Mapping identifies which application handler should be used for a given form


Design - Configuring Inbound Processing for Interactive Offline Form

Most important Components

Inbound handler class-

  • The inbound handler for a form should be defined in the transaction SFP on the properties tab.


Function Modules, Interfaces –

  • To process inbound PDFs, an application has to implement the interface IF_FP_OFFLINE.

  • The method HANDLE_PDF is called with the PDF document the extracted form data in XML form the form-template name.

  • Function module FP_FUNCTION_MODULE_NAME for retrieving the name of a generated function module to convert the XML form data into the dictionary structures that are defined in the form interface. The structure of the XML data reflects the structure of the form context.

  • The generated function module transforms context changes back, as far as possible

  • The system administrator has to activate the SMTP plugin.

  •  In transaction SO50, the handler class CL_FP_INBOUND_HANDLER has to be defined as processing exit for the mail addresses for which offline PDFs will be Retrieve




Design - Configuring Inbound Processing for Interactive Offline Form


System Configuration

  • The application must configure BCS appropriately in transaction SO50.

  • The main inbound handler class CL_FP_INBOUND_HANDLER must be entered as the Exit Name for the inbound e-mail address.

  • The system logs the main inbound processing steps under the object FP in the application log.

  • You can evaluate the log entries in transaction SLG1.



SO50 System Configuration


Inbound Handler

  • Inbound Exit classes CL_FP_INBOUND_HANDLER are singleton classes that must implement the IF_INBOUND_EXIT_BCS interface.

  • Must implement the two methods defined on this interface.

  • CREATE_INSTANCE – contains code to create the singleton instance. Must set the returning parameter RO_REF to the instance of the class.

  • PROCESS_INBOUND – contains code to process the inbound email.

  • Import parameter: IO_SREQ type ref to CL_SEND_REQUEST_BCS

  • Contains inbound email document class CL_DOCUMENT_BCS Can be used to create reply emails.

  • Import parameter: IT_RECIPIENTS type BCSY_SMTPA – list of SMTP recipients.

  • Import parameter: IT_DOCTYPES type BCSY_SODOC – list of documents types make up the email.

  • Exporting parameter: E_RETCODE – used to control processing of other

  • Inbound Exit processes in the call sequence.

  • Exporting parameter: ES_T100MSG – used to store T100 messages that can be written to a log.



Inbound Class


Example Programs and Interactive forms for Reference

  • Offline form: FP_TEST_IA_01

  • Inbound handler class: CL_FP_OFFLINE_FP_TEST_IA_01

  • Generation and dispatch: Test report FP_TEST_IA_01

  • Trigger for inbound processing of an offline form (no e-mail): FP_TEST_INBOUND


Below is the example of form which can be used to test :


Example of Interactive form


Code to handle the incoming email using the inbound handler class
method IF_FP_OFFLINE~GET_INSTANCE.
CREATE OBJECT ro_instance TYPE ZCL_INBOUND_HANLDER_BUPA.
endmethod.



method if_fp_offline~handle_pdf.
constants lc_object type balobj_d value 'FORM_TEST'.
constants lc_subobj type balsubobj value 'OTHERS'.
data ls_log_header type bal_s_log.
data ls_msg type bal_s_msg.
data : lv_fm_name type rs38l_fnam,
t_return type standard table of bapiret2,
t_per_info type standard table of smum_xmltb.
data lv_url type string.
data lv_preprinted type fpboolean.
data lv_effchangedate type sydate.
data lv_employeeid type string.
data lv_department type string.
data lv_name type string.
data ls_newaddress type fptest_smpladd.
data ls_oldaddress type fptest_smpladd.
data ls_groupstates type fptest_states.
data :
lv_name1 type name1,
lv_street type ad_street,
lv_housenumber type ad_hsnm1,
lv_country type land1,
lv_postalcode type ad_pstcd1,
lv_telcountry type ad_comctry,
lv_telephone type ad_tlnmbr.
* Check parameters.
if iv_form_name is initial or iv_pdf is initial or iv_xml is initial.
raise exception type cx_fp_offline
exporting
textid = cx_fp_offline=>cx_fp_offline.
endif.

* Create application log.
ls_log_header-object = lc_object.
ls_log_header-subobject = lc_subobj.
ls_log_header-aldate_del = sy-datum + 90.
call function 'BAL_LOG_CREATE'
exporting
i_s_log = ls_log_header.

move 'S' to ls_msg-msgty.
move 'AD' to ls_msg-msgid.
move '010' to ls_msg-msgno.

* Write header log entry.
ls_msg-msgv1 = cl_abap_classdescr=>get_class_name( me ).
replace '\CLASS=' in ls_msg-msgv1 with ''.
ls_msg-detlevel = '1'.
call function 'BAL_LOG_MSG_ADD'
exporting
i_s_msg = ls_msg
exceptions
others = 0.

* Parse the XML data and write the field values into the log,
* using the generated function module to ease this task.
try.
call function 'FP_FUNCTION_MODULE_NAME'
exporting
i_name = iv_form_name
importing
ev_funcname_inbound = lv_fm_name.
catch cx_fp_api_repository cx_fp_api_usage cx_fp_api_internal.
message id 'FPAPIGENERIC' type 'E' number '000' with iv_form_name.
endtry.

if iv_form_lang is not initial.
call function 'SCP_MIXED_LANGUAGES_1_INIT'.
call function 'SCP_MIXED_LANGUAGES_1_SWITCH'
exporting
need_lang = iv_form_lang
exceptions
others = 0.
endif.


call function lv_fm_name
exporting
iv_xml_data = iv_xml
importing
name1 = lv_name1
street = lv_street
house_no = lv_housenumber
country = lv_country
postl_cod1 = lv_postalcode
telcountry = lv_telcountry
telephone = lv_telephone
exceptions
usage_error = 1
system_error = 2
internal_error = 3
others = 4.

if sy-subrc is not initial.
message id sy-msgid type sy-msgty number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.
call function 'SMUM_XML_PARSE'
exporting
xml_input = iv_xml
tables
xml_table = t_per_info
return = t_return.
data : lfs_per_info type smum_xmltb.
loop at t_per_info into lfs_per_info.
case lfs_per_info-cname.
when 'NAME1'.
lv_name1 = lfs_per_info-cvalue.
when 'STREET'.
lv_street = lfs_per_info-cvalue.
when 'HOUSE_NO'.
lv_housenumber = lfs_per_info-cvalue.
when 'COUNTRY'.
lv_country = lfs_per_info-cvalue.
when 'POSTL_COD1'.
lv_postalcode = lfs_per_info-cvalue.
when 'TELCOUNTRY'.
lv_telcountry = lfs_per_info-cvalue.
when 'TELEPHONE'.
lv_telephone = lfs_per_info-cvalue.
when others.
endcase.
endloop.
if iv_form_lang is not initial.
call function 'SCP_MIXED_LANGUAGES_1_NORMAL'.
call function 'SCP_MIXED_LANGUAGES_1_FINISH'.
endif.

* Make the log entries.
define add_message.
move &1 to ls_msg-msgv1.
move ':' to ls_msg-msgv2.
move &2 to ls_msg-msgv3.
move '2' to ls_msg-detlevel.
call function 'BAL_LOG_MSG_ADD'
exporting
i_s_msg = ls_msg
exceptions
others = 0.
end-of-definition.
** Declarations


add_message 'NAME1' lv_name1.
add_message 'STREET' lv_street.
add_message 'HOUSE_NO' lv_housenumber.
add_message 'COUNTRY' lv_country.
add_message 'POSTL_COD1' lv_postalcode.
add_message 'TELCOUNTRY' lv_telcountry.
add_message 'TELEPHONE' lv_telephone.
**---------------------------------------------------------------------
*--------------.
types: begin of ty_bpdata,
* sel(1) type c,
businesspartner type bapibus1006_head-bpartner,
bpvendor type lfa1-lifnr,
lifnr type lfa1-lifnr,
reference(25) type c,
msg_type type bapiret2-type,
message type bapiret2-message,
traffic(4) type c.
types: end of ty_bpdata.
data: lt_vend1 type standard table of mere_outtab_mkvz,
ls_vend1 like line of lt_vend1,
lt_vend_main type standard table of zmere_outtab_mkvz,
ls_vend_main like line of lt_vend_main,
lt_vend type standard table of zmere_outtab_mkvz,
ls_vend like line of lt_vend,
* lt_lfa1 TYPE STANDARD TABLE OF lfa1,
* lt_lfb1 TYPE STANDARD TABLE OF lfb1,
* lt_lfm1 TYPE STANDARD TABLE OF lfm1,
* lt_wyt3 TYPE STANDARD TABLE OF wyt3,
* ls_lfa1 LIKE LINE OF lt_lfa1,
lt_lfa1 type standard table of lfa1,
ls_lfa1 like line of lt_lfa1,
lt_lfb1 type standard table of lfb1,
ls_lfb1 like line of lt_lfb1,
lt_lfm1 type standard table of lfm1,
ls_lfm1 like line of lt_lfm1,
lt_wyt3 type standard table of wyt3,
ls_wyt3 like line of lt_wyt3,
lt_adrc type standard table of adrc,
ls_adrc like line of lt_adrc,
lt_bpdata_temp type standard table of ty_bpdata,
ls_bpdata_temp like line of lt_bpdata_temp,
lt_bpdata type standard table of ty_bpdata,
ls_bpdata like line of lt_bpdata,
ls_bapiret2 type bapiret2.

data: partner type bapibus1006_head-bpartner,
partnercategory type bapibus1006_head-partn_cat,
partnertype type bapibus1006_head-partn_typ,
partnergroup type bapibus1006_head-partn_grp,
partnerextno type bapibus1006_head-extern_no,
centraldata type bapibus1006_central,
centraldataperson type bapibus1006_central_person,
centraldataorganization type bapibus1006_central_organ,
adressdata type bapibus1006_address,
businesspartner type bapibus1006_head-bpartner,
lt_telefondata type standard table of bapiadtel,
ls_telefondata type bapiadtel,
lt_faxdata type standard table of bapiadfax,
ls_faxdata type bapiadfax,
lt_e_maildata type standard table of bapiadsmtp,
ls_e_maildata type bapiadsmtp,
lt_return type standard table of bapiret2,
ls_return type bapiret2,
lv_msg type c length 1,
lv_return type bapiret2,
lv_return2 type standard table of bapiret2,
lv_message type string,
lv_file type string,
lv_string type string,
lv_minbw type string,
lv_azekorg type string.

data: ls_vend_master_data type vmds_ei_main,
lt_vendors type vmds_ei_extern_t,
ls_vendors type vmds_ei_extern,
ls_vend_header type vmds_ei_header,
ls_vend_central_data type vmds_ei_central_data,
ls_vend_company_data type vmds_ei_vmd_company,
ls_purchasing_data type vmds_ei_vmd_purchasing,
ls_vend_central type vmds_ei_vmd_central,
ls_vend_address type cvis_ei_address1,
ls_vend_bankdetail type cvis_ei_bankdetail,
lt_vend_bankdetails type cvis_ei_bankdetail_t,
ls_vend_bankdetails type cvis_ei_cvi_bankdetail,
lt_vend_company type vmds_ei_company_t,
ls_vend_company type vmds_ei_company,
lt_vend_purchasing type vmds_ei_purchasing_t,
ls_vend_purchasing type vmds_ei_purchasing,
lt_vend_functions type vmds_ei_functions_t,
ls_vend_functions type vmds_ei_functions.

data: es_vend_master_data_correct type vmds_ei_main,
es_vend_message_correct type cvis_message,
es_vend_master_data_defective type vmds_ei_main,
es_vend_message_defective type cvis_message.
*-- Fill the BP data

refresh: lt_telefondata.
partnercategory = '2'.
partnergroup = 'Y001'.
centraldata-title_key = '0003'.
centraldataorganization-name1 = lv_name1.
adressdata-standardaddress = abap_true.
adressdata-langu = 'EN'.
adressdata-city = 'Test'.
adressdata-postl_cod1 = lv_postalcode.
adressdata-street = lv_street.
adressdata-house_no = lv_housenumber.
adressdata-country = lv_country.
ls_telefondata-country = lv_telcountry.
ls_telefondata-std_no = 'X'.
ls_telefondata-telephone = lv_telephone.
append ls_telefondata to lt_telefondata.
*-- Create BUPA
clear: businesspartner, lv_return.
call function 'BAPI_BUPA_CREATE_FROM_DATA'
exporting
partnercategory = partnercategory
partnergroup = partnergroup
centraldata = centraldata
centraldataorganization = centraldataorganization
addressdata = adressdata
importing
businesspartner = businesspartner
tables
telefondata = lt_telefondata

return = lv_return2

.

call function 'BAPI_TRANSACTION_COMMIT'
exporting
wait = 'X'
importing
return = lv_return.
if businesspartner is not initial.
ls_bpdata_temp-businesspartner = businesspartner.

endif.
add_message 'BUPANUM' businesspartner .
* Save the log.
call function 'BAL_DB_SAVE'
exporting
i_save_all = abap_true
exceptions
others = 0.
call function 'POPUP_TO_INFORM'
exporting
titel = 'Busines Partner Creation'
txt1 = | Busines Partner { businesspartner } Created |
txt2 = ' '
txt3 = ' '
txt4 = ' '.

lv_objtype TYPE sibftypeid,
lv_event TYPE sibfevent,
lv_objkey TYPE sibfinstid.
lv_objtype = 'ZCL_BUPA'.
lv_event = 'BUPA_CREATED.
• Set up the LPOR instance id
ls_zcl_key- businesspartner = businesspartner .
MOVE ls_zcl_key TO lv_objkey.
• Raise the event
TRY.
CALL METHOD cl_swf_evt_event=>raise
EXPORTING
im_objcateg = cl_swf_evt_event=>mc_objcateg_cl
im_objtype = lv_objtype
im_event = lv_event
im_objkey = lv_objkey
• IM_EVENT_CONTAINER =
.
CATCH cx_swf_evt_invalid_objtype .
CATCH cx_swf_evt_invalid_event .
ENDTRY.
COMMIT WORK.

endmethod.

Error Handling :

Error handling can be done using the SLG1 transaction of code by giving the form object FP or Form test in the above example. However since all users cannot have the access to the transaction a new report can be developed by using the below logic :

  • Fetching the log details from SLG1 with the OBJECT 'FORM_TEST' for the incoming emails with the function block: 'GHO_MEAS_APPLICATIONLOG_GET'.

Labels in this area