SAP Document and Reporting Compliance for India: Electronic Invoice in Utilities using Extensibility

Estimated read time 29 min read

You want to enable your system to create electronic documents for invoices posted in Utilities using SAP Document and Reporting Compliance, cloud edition. In this blog, we’ll show you an example on how this can be achieved using extensibilty.  

Prerequisite: 

Before you begin ensure that you have implemented the SAP Notes listed in 3569761 – Electronic Document Processing for India: Electronic Invoice using SAP Document and Reporting Compliance, Cloud Edition – Implementation Overview. You can also refer the SAP Help Portal for more information, see Electronic Document Processing. 

Steps to Create Electronic Documents

Append Structure Creation
Create a ‘Z’ append structure to map utilities-specific fields to the source structure EDOC_IN_GEN_SOURCE. Include the following utilities-specific fields to the append structure. 
Example: 

Field Name 

Component Type 

Description 

DOC_HEADER_ISU 

EDOC_ERDK 

eDocument: IS-U- Print Document/Header Data 

DOC_ITEM_ISU 

EDOC_ERDZ_TAB 

eDocument: IS-U Print Document – Item Data 

FKKVKP_ISU 

FKKVKP 

Contract Account Partner- Specific 

DFKKKO_ISU 

DFKKKO 

Header Data in Open Item Accounting Document 

 Implement FQEVENT R433 (Electronic Document Creation)
Create a ‘Z’ function module to implement
FQEVENT R433, using the method PREPARE_EDOCUMENTS from the class CL_EDOC_SOURCE in FM. This method utilizes the factory class of eDocument IS-U to get an instance of the eDocument IS-U class. 
Sample Code:  
FUNCTION ZEDOC_ISU_IN_R433 .
*”———————————————————————-
*”*”Local Interface:
*” IMPORTING
*” REFERENCE(X_BUPA) TYPE EKUN_EXT
*” REFERENCE(X_FKKVKP) TYPE FKKVKP
*” REFERENCE(X_PRINTDOC) TYPE ISU21_PRINT_DOC
*” REFERENCE(X_PRINTDOCNO) LIKE ERDK-OPBEL
*” REFERENCE(X_INVOICE_UNIT) TYPE ISU21_INVOICE_UNIT
*” REFERENCE(X_PARAM) TYPE ISU21_INVOICE_PARAM
*” TABLES
*” T_VKK_DOC_ID TYPE ISU21_T_VKK_DOC_ID
*” T_BILL_DOC TYPE ISU2A_T_BILL_DOC
*”———————————————————————-

DATA: lv_active TYPE edoc_active,
lv_msgtyp TYPE symsgty,
lv_bukrs TYPE bukrs,
lv_land1 TYPE land1,
ls_erdk TYPE erdk,
ls_fkkvkp TYPE fkkvkp,
ls_bapiret TYPE bapiret2,
ls_source_data TYPE edoc_src_data_isu_invoice,
ls_t001 TYPE t001,
lt_edocument TYPE edoc_instance_tab,
lo_source_data TYPE REF TO cl_edoc_source,
lo_edocument TYPE REF TO cl_edocument,
lx_error TYPE REF TO cx_edocument,
ld_source_data TYPE REF TO data,
inv_doc LIKE LINE OF t_vkk_doc_id,
fkop LIKE LINE OF inv_doc-vkk_doc-t_fkkop.

FIELD-SYMBOLS: <ls_edocument> TYPE edoc_instance.

FREE: lo_source_data,
lo_edocument.

CLEAR: lv_active,
lv_msgtyp,
lv_bukrs,
ls_erdk,
ls_fkkvkp,
ls_bapiret,
ls_source_data,
ls_t001,
lt_edocument[],
inv_doc,
fkop.

“Print Document Header
ls_erdk = x_printdoc-erdk.

READ TABLE t_vkk_doc_id INTO inv_doc WITH KEY id = ‘A’.
IF sy-subrc = 0.
LOOP AT inv_doc-vkk_doc-t_fkkop INTO fkop
WHERE NOT bukrs IS INITIAL.
lv_bukrs = fkop-bukrs.
EXIT.
ENDLOOP.
IF sy-subrc = 0.
SELECT SINGLE land1
INTO lv_land1
FROM t001
WHERE bukrs = lv_bukrs.
IF sy-subrc EQ 0 AND lv_land1 EQ ‘IN’.
SELECT SINGLE active
INTO lv_active
FROM edocompanyactiv
WHERE bukrs = lv_bukrs
AND source_type = cl_edoc_source_isu_invoice=>gc_src_isu_invoice.
IF lv_active = ‘X’.

ls_fkkvkp = x_fkkvkp.

TRY.
ls_source_data-fkkvkp = ls_fkkvkp.
MOVE-CORRESPONDING inv_doc-vkk_doc-fkkko TO ls_source_data-dfkkko.
SELECT SINGLE *
FROM t001
INTO ls_t001
WHERE bukrs = lv_bukrs.
IF sy-subrc EQ 0.
ls_source_data-t001 = ls_t001.
ls_source_data-source_header-land = ls_t001-land1.
ENDIF.
ls_source_data-source_header-bukrs = lv_bukrs.
ls_source_data-source_header-source_type = cl_edoc_source_isu_invoice=>gc_src_isu_invoice.
ls_source_data-document_header = ls_erdk.
ls_source_data-document_item = x_printdoc-t_erdz.
* Fill source document key
cl_edoc_source_isu_invoice=>pack_key( EXPORTING iv_opbel = ls_erdk-opbel
IMPORTING ev_key = ls_source_data-source_header-source_key ).

GET REFERENCE OF ls_source_data INTO ld_source_data.
lo_source_data = cl_edoc_source_isu_invoice=>create_instance( ld_source_data ).

IF lo_source_data IS BOUND.

lt_edocument = lo_source_data->prepare_edocuments(
iv_update_task = abap_true
iv_hook = abap_true ).
LOOP AT lt_edocument ASSIGNING <ls_edocument>.
IF <ls_edocument>-edocument IS BOUND.
<ls_edocument>-edocument->create_edocument( ).
ENDIF.
ENDLOOP.

ENDIF.
CATCH cx_edocument INTO lx_error.

LOOP AT lx_error->mt_message INTO ls_bapiret.
“Default type Error
lv_msgtyp = ‘E’.
IF lo_edocument IS BOUND.
“eDocument has been created
IF lo_edocument->mv_saved_in_db = abap_true.
lv_msgtyp = ‘I’.
ENDIF.
ENDIF.
MESSAGE ID ls_bapiret-id TYPE lv_msgtyp NUMBER ls_bapiret-number
WITH ls_bapiret-message_v1 ls_bapiret-message_v2
ls_bapiret-message_v3 ls_bapiret-message_v4.
ENDLOOP.

ENDTRY.
ENDIF.
ENDIF.
ENDIF.
ENDIF.

ENDFUNCTION. Implement FQEVENT R428 (Reversal)
Similarly, create a ‘Z’ function module to implement FQEVENT R428, using the same method as above for reversal process.
Sample Code:  FUNCTION zedoc_isu_in_r428. “#EC CI_FUNCTION
*”———————————————————————-
*”*”Local Interface:
*” IMPORTING
*” REFERENCE(X_REVERSAL_DOC) TYPE ISU21_CANC_DOC OPTIONAL
*” REFERENCE(X_INVOICE_DOC) TYPE ISU21_INVOICE_UNIT OPTIONAL
*” REFERENCE(X_REVERSAL_PARAM) TYPE ISU21_CANC_PARAM OPTIONAL
*” REFERENCE(X_INVOICE_PARAM) TYPE ISU21_INVOICE_PARAM OPTIONAL
*” REFERENCE(X_CALL_ID) TYPE C
*” TABLES
*” XYT_EITR TYPE ISU21_T_EITR
*”———————————————————————-

DATA: lv_bukrs TYPE bukrs,
lv_active TYPE edoc_active,
lv_invopbel TYPE opbel_kk,
lv_msgtyp TYPE symsgty,
ls_erdk TYPE erdk,
ls_fkkvkp TYPE fkkvkp,
ls_bukrs TYPE eitr,
ls_t001 TYPE t001,
ls_erdb TYPE erdb,
ls_dfkkko TYPE dfkkko,
ls_source_data TYPE edoc_src_data_isu_invoice,
ls_bapiret TYPE bapiret2,
lt_erdz TYPE edoc_erdz_tab,
lt_t001z TYPE STANDARD TABLE OF t001z,
lt_edocument TYPE edoc_instance_tab,
lo_source_data TYPE REF TO cl_edoc_source,
lo_edocument TYPE REF TO cl_edocument,
lx_error TYPE REF TO cx_edocument,
ld_source_data TYPE REF TO data.

FIELD-SYMBOLS: <ls_edocument> TYPE edoc_instance.

FREE: lo_source_data,
lo_edocument.

CLEAR: lv_bukrs,
lv_active,
lv_invopbel,
lv_msgtyp,
ls_erdk,
ls_fkkvkp,
ls_bukrs,
ls_t001,
ls_erdb,
ls_dfkkko,
ls_source_data,
ls_bapiret,
lt_erdz[],
lt_t001z[],
lt_edocument[].

* This event should be trigger only for reversal process
IF x_call_id = ‘R’.

LOOP AT x_reversal_doc-t_eitr INTO ls_bukrs
WHERE bukrs IS NOT INITIAL.
lv_bukrs = ls_bukrs-bukrs.
ENDLOOP.

SELECT SINGLE *
FROM t001
INTO ls_t001
WHERE bukrs = lv_bukrs.
IF ls_t001-land1 EQ ‘IN’.

SELECT SINGLE active
INTO lv_active
FROM edocompanyactiv
WHERE bukrs = lv_bukrs
AND source_type = cl_edoc_source_isu_invoice=>gc_src_isu_invoice.
IF lv_active = ‘X’ AND
x_reversal_doc-new_print_doc-erdk-opbel IS NOT INITIAL.

ls_erdk = x_reversal_doc-new_print_doc-erdk.
lt_erdz = x_reversal_doc-new_print_doc-t_erdz.
ls_fkkvkp = x_reversal_doc-acc-fkkvkp.

LOOP AT x_reversal_doc-old_print_doc-t_erdb INTO ls_erdb
WHERE doc_id = ‘A’ OR doc_id = ‘S’.
lv_invopbel = ls_erdb-invopbel.
ENDLOOP.

SELECT SINGLE *
FROM dfkkko
INTO ls_dfkkko
WHERE opbel = lv_invopbel.
IF sy-subrc EQ 0.
ls_source_data-dfkkko = ls_dfkkko.
ENDIF.

SELECT *
FROM t001z
INTO TABLE lt_t001z
WHERE bukrs = lv_bukrs.
IF sy-subrc EQ 0.
ls_source_data-t001z = lt_t001z.
ENDIF.
TRY.

* Source structure mapping
ls_source_data-document_header = ls_erdk.
ls_source_data-document_item = lt_erdz .
ls_source_data-source_header-source_type = cl_edoc_source_isu_invoice=>gc_src_isu_invoice.
ls_source_data-source_header-bukrs = lv_bukrs.
ls_source_data-source_header-land = ls_t001-land1.
ls_source_data-t001 = ls_t001.
ls_source_data-fkkvkp = ls_fkkvkp.
* fill source document key
cl_edoc_source_isu_invoice=>pack_key( EXPORTING iv_opbel = ls_erdk-opbel
IMPORTING ev_key = ls_source_data-source_header-source_key ).

GET REFERENCE OF ls_source_data INTO ld_source_data.
lo_source_data = cl_edoc_source_isu_invoice=>create_instance( ld_source_data ).

IF lo_source_data IS BOUND.

lt_edocument = lo_source_data->prepare_edocuments(
iv_update_task = abap_true
iv_hook = abap_true ).
LOOP AT lt_edocument ASSIGNING <ls_edocument>.
IF <ls_edocument>-edocument IS BOUND.
<ls_edocument>-edocument->create_edocument( ).
ENDIF.
ENDLOOP.

ENDIF.
CATCH cx_edocument INTO lx_error.

LOOP AT lx_error->mt_message INTO ls_bapiret.
“Default type Error
lv_msgtyp = ‘E’.
IF lo_edocument IS BOUND.
“eDocument has been created
IF lo_edocument->mv_saved_in_db = abap_true.
lv_msgtyp = ‘I’.
ENDIF.
ENDIF.
MESSAGE ID ls_bapiret-id TYPE lv_msgtyp NUMBER ls_bapiret-number
WITH ls_bapiret-message_v1 ls_bapiret-message_v2
ls_bapiret-message_v3 ls_bapiret-message_v4.
ENDLOOP.

ENDTRY.
ENDIF.
ENDIF.
ENDIF.

ENDFUNCTION. Create Factory ClassCreate a ‘Z’ factory class to get the instance of eDocument IS-U class by inheriting CL_EDOC_FACTORY class and redefine its method CREATE_EDOC_INSTANCE. Example: ZCL_EDOC_FACTORY_IN_ISU
Sample Code:   METHOD create_edoc_instances.

DATA: lv_land_iso TYPE edoc_land,
lv_error_txt TYPE string,
ls_source_header TYPE edoc_src_header,
lo_edocument TYPE REF TO zcl_edocument_in_isu.

CLEAR: lv_land_iso,
lv_error_txt,
ls_source_header,
lo_edocument,
et_edocument_obj.

* Country
ls_source_header = io_source->get_header( ).
CALL FUNCTION ‘COUNTRY_CODE_SAP_TO_ISO’
EXPORTING
sap_code = ls_source_header-land
IMPORTING
iso_code = lv_land_iso
EXCEPTIONS
not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE e881(b1) WITH ls_source_header-land INTO lv_error_txt.
ENDIF.
IF lv_land_iso <> ‘IN’.
RETURN.
ENDIF.

CREATE OBJECT lo_edocument
EXPORTING
io_source_data = io_source
iv_update_task = iv_update_task.

APPEND lo_edocument TO et_edocument_obj.

ENDMETHOD.

          2. Configure this ‘Z’ eDocument factory class in the view EDOFACTORYV using the transaction SM30. 
               Example:

Source Type 

Factory Class 

ISU_INVOIC 

‘Z’ factory class name (your factory class that you just created) 

Create eDocument ClassCreate a ‘Z’ eDocument class by inheriting CL_EDOCUMENT_IN_EINV class.  Add the CONSTRUCTOR method to your ‘Z’ eDocument class to map the ‘Z’ eDocument IS-U class name to ms_edocument-edocument_class.   Redefine the method DETERMINE_EDOC_TYPE to assign the eDocument type.Use the table TFK003EDOC to configure eDocument type against the accounting document type
Example

Country/Region 

Application Area 

Document Type 

eDocument Type 

IN 

Utility Company 

FA 

IN_EINV 

IN 

Utility Company 

ST 

IN_EINV 

 Add the class CL_EDOC_PROCESS as ‘Friends’ of ‘Z’ eDocument class. 
Sample Code:  
METHOD determine_edoc_type.

DATA: lv_blart TYPE blart,
ls_tfk003edoc TYPE tfk003edoc.

CLEAR: lv_blart,
ls_tfk003edoc.

IF mo_source->mv_source_type = cl_edoc_source_isu_invoice=>gc_src_isu_invoice.
lv_blart = mo_source->get_blart( ).
* ls_tfk003edoc = me->select_tfk003edoc( iv_land = ms_edocument-land iv_blart = lv_blart ).
DATA: l_applk TYPE tfkfbs-applk.

CLEAR: l_applk,
ls_tfk003edoc.

CALL FUNCTION ‘FKK_GET_APPLICATION’
IMPORTING
e_applk = l_applk
EXCEPTIONS
no_appl_selected = 1
OTHERS = 2.
IF sy-subrc EQ 0.
SELECT SINGLE *
FROM tfk003edoc
INTO ls_tfk003edoc
WHERE land = ms_edocument-land
AND applk = l_applk
AND blart = lv_blart.
ENDIF.
rv_edoc_type = ls_tfk003edoc-edoc_type.
ELSE.
rv_edoc_type = super->determine_edoc_type( ).
ENDIF.
ms_edocument-edoc_type = rv_edoc_type.

determine_edoc_type_global(
CHANGING
cv_edoc_type = rv_edoc_type ).

ENDMETHOD.
METHOD constructor.

super->constructor( io_source_data = io_source_data
iv_edoc_guid = iv_edoc_guid
iv_land = iv_land
iv_generic_badi_filter_adaptor = ‘ISU_INVOIC’
iv_update_task = iv_update_task ).

ms_edocument-land = ‘IN’.
ms_edocument-edocument_class = ‘ZCL_EDOCUMENT_IN_ISU’.

ENDMETHOD.

Create Mapping ClassCreate a ‘Z’ mapping class by inheriting CL_EDOC_MAP_IN_EINV class.
Example: ZCL_EDOC_MAP_IN_EINV_ISU
Redefine the method MAP_GEN_EINVR1 of the newly created class to fill the proxy structure with utilities data.Implement the BAdI EDOC_INTERFACE_CONNECTOR (Enhancement Spot – ES_EDOCUMENT) with specific filters. Inherit the class CL_EDOC_INTF_CONN_IN_EINV_AIF and delete the interfaces in ‘Z’ BAdI class. 
Redefine the method IF_EDOC_INTF_CONN_IMPL~GET_SOURCE_DATA to map the IS-U print document data to rd_source_data.Deactivate the standard BAdI enhancement implementation EI_EDOC_INTF_CONN_IN_EINV_AIF.  Configure your mapping class in the view EDOMAPCLASSDETV using the transaction SM30. 
Example:

eDocument Process 

Version 

Interface ID 

eDocument Type 

Source Type 

Mapping Class 

INEINV 

1 

IN_EINV_GENERATE_REQ 

IN_EINV 

ISU_INVOIC 

<Your mapping class> 

INEINV 

2 

IN_EINV_GENERATE_REQ 

IN_EINV 

ISU_INVOIC 

<Your mapping class> 


Sample Code for Get Source Data  
METHOD if_edoc_intf_conn_impl~get_source_data.

DATA : ls_isu_invoice TYPE edoc_src_data_isu_invoice,
lo_edocument_in TYPE REF TO zcl_edocument_in_isu,
lo_source TYPE REF TO cl_edoc_source,
ls_src_header TYPE edoc_src_header,
ls_source TYPE edoc_in_gen_source,
lv_class_name TYPE edoc_mapping_class.

DATA : lv_doc_header TYPE string,
lv_doc_item TYPE string,
lv_t001 TYPE string,
lv_t001z TYPE string,
lv_fkkvkp TYPE string,
lv_dfkkko TYPE string.

CONSTANTS: lc_document_header TYPE char15 VALUE ‘DOCUMENT_HEADER’.

FIELD-SYMBOLS: <fs_doc_header> TYPE any,
<fs_doc_header1> TYPE any,
<fs_doc_item> TYPE any,
<fs_doc_item1> TYPE any,
<fs_t001> TYPE any,
<fs_t0011> TYPE any,
<fs_t001z> TYPE any,
<fs_t001z1> TYPE any,
<fs_fkkvkp> TYPE any,
<fs_fkkvkp1> TYPE any,
<fs_dfkkko> TYPE any,
<fs_dfkkko1> TYPE any.

FIELD-SYMBOLS: <ls_source> TYPE edoc_in_gen_source.

TRY.
CALL METHOD super->if_edoc_intf_conn_impl~get_source_data
EXPORTING
io_edocument = io_edocument
receiving
rd_source_data = rd_source_data.

IF io_edocument->ms_edocument-source_type = ‘ISU_INVOIC’.
* Retrieve source document and map according to source type
lo_source = io_edocument->get_source( ).
ls_src_header = lo_source->get_header( ).

lo_source->get_data( IMPORTING es_data = ls_isu_invoice ).

lo_edocument_in ?= io_edocument.
ls_source-reference-edoc_guid = lo_edocument_in->ms_edocument-edoc_guid.
ls_source-source_header = ls_src_header.
ls_source-reference-edoc_guid = io_edocument->ms_edocument-edoc_guid.

ASSIGN COMPONENT ‘DOC_HEADER_ISU’ OF STRUCTURE ls_source TO <fs_doc_header1>.
IF <fs_doc_header1> IS ASSIGNED.
lv_doc_header = ‘LS_SOURCE-DOC_HEADER_ISU_HU’.
ASSIGN (lv_doc_header) TO <fs_doc_header>.
ASSIGN COMPONENT lc_document_header OF STRUCTURE ls_isu_invoice TO <fs_doc_header>.
<fs_doc_header1> = <fs_doc_header>.
ENDIF.

ASSIGN COMPONENT ‘DOC_ITEM_ISU’ OF STRUCTURE ls_source TO <fs_doc_item1>.
IF <fs_doc_item1> IS ASSIGNED.
lv_doc_item = ‘LS_SOURCE-DOC_ITEM_ISU_HU’.
ASSIGN (lv_doc_item) TO <fs_doc_item>.
ASSIGN COMPONENT ‘DOCUMENT_ITEM’ OF STRUCTURE ls_isu_invoice TO <fs_doc_item>.
<fs_doc_item1> = <fs_doc_item>.
ENDIF.

ASSIGN COMPONENT ‘FKKVKP’ OF STRUCTURE ls_source TO <fs_fkkvkp1>.
IF <fs_fkkvkp1> IS ASSIGNED.
lv_fkkvkp = ‘LS_SOURCE-FKKVKP’.
ASSIGN (lv_fkkvkp) TO <fs_fkkvkp>.
ASSIGN COMPONENT ‘FKKVKP’ OF STRUCTURE ls_isu_invoice TO <fs_fkkvkp>.
<fs_fkkvkp1> = <fs_fkkvkp>.
ENDIF.

ASSIGN COMPONENT ‘DFKKKO’ OF STRUCTURE ls_source TO <fs_dfkkko1>.
IF <fs_dfkkko1> IS ASSIGNED.
lv_dfkkko = ‘LS_SOURCE-DFKKKO’.
ASSIGN (lv_dfkkko) TO <fs_dfkkko>.
ASSIGN COMPONENT ‘DFKKKO’ OF STRUCTURE ls_isu_invoice TO <fs_dfkkko>.
<fs_dfkkko1> = <fs_dfkkko>.
ENDIF.

CREATE DATA rd_source_data TYPE edoc_in_gen_source.
ASSIGN rd_source_data->* TO <ls_source>.
MOVE-CORRESPONDING ls_source TO <ls_source>.
ENDIF.
CATCH cx_edocument.
ENDTRY.

ENDMETHOD.

 

Maintain the Required CustomizationsActivate company code for ISU_INVOIC source type in the view EDOCOMPANYACTIV for eDocument creation.
Example:

Company Code 

Source Type 

Application Active 

Your company code 

ISU_INVOICE 

X 

Maintain the view EDOPROCSPINTDETV with the process, process step, eDocument type, source type (ISU_INVOIC).   
Example:

eDocument Process 

Version 

Process Step 

eDocument Type 

Source type 

Proc. Step Variant 

Interface ID 

INEINV 

1 

REQ_CANCEL 

IN_EINV 

ISU_INVOIC 

EWBCANC 

IN_EINV_CANC_EWB_REQ 

INEINV 

1 

REQ_CANCEL 

IN_EINV 

ISU_INVOIC 

EWBCANC 

IN_EINV_CANC_EWB_REQ 

INEINV 

1 

REQ_CANCEL 

IN_EINV 

ISU_INVOIC 

EWBCANC 

IN_EINV_CANC_EWB_REQ 

INEINV 

1 

REQ_CANCEL 

IN_EINV 

ISU_INVOIC 

EWBCANC 

IN_EINV_CANC_EWB_REQ 

INEINV 

1 

GET_DETAIL 

IN_EINV 

ISU_INVOIC 

IRNDOC 

IN_EINV_GET_DET_DOC_NUM_REQ 

INEINV 

1 

GET_DETAIL 

IN_EINV 

ISU_INVOIC 

IRNDOC 

IN_EINV_GET_DET_DOC_NUM_REQ 

INEINV 

1 

GET_DETAIL 

IN_EINV 

ISU_INVOIC 

IRNDOC 

IN_EINV_GET_DET_DOC_NUM_REQ 

INEINV 

1 

GET_DETAIL 

IN_EINV 

ISU_INVOIC 

IRNDOC 

IN_EINV_GET_DET_DOC_NUM_REQ 

By following these steps, you can efficiently create electronic documents for invoices in the utilities sector, ensuring compliance and enhancing operational efficiency. 

Don’t forget to test it thoroughly. 

We hope this blog post was useful for you! You can leave a comment here or continue browsing our community for more blog posts on SAP Document and Reporting Compliance topics. 

Looking forward to seeing you here again! 

 

​ You want to enable your system to create electronic documents for invoices posted in Utilities using SAP Document and Reporting Compliance, cloud edition. In this blog, we’ll show you an example on how this can be achieved using extensibilty.  Prerequisite: Before you begin ensure that you have implemented the SAP Notes listed in 3569761 – Electronic Document Processing for India: Electronic Invoice using SAP Document and Reporting Compliance, Cloud Edition – Implementation Overview. You can also refer the SAP Help Portal for more information, see Electronic Document Processing.  Steps to Create Electronic DocumentsAppend Structure CreationCreate a ‘Z’ append structure to map utilities-specific fields to the source structure EDOC_IN_GEN_SOURCE. Include the following utilities-specific fields to the append structure. Example:  Field Name Component Type Description DOC_HEADER_ISU  EDOC_ERDK  eDocument: IS-U- Print Document/Header Data  DOC_ITEM_ISU  EDOC_ERDZ_TAB  eDocument: IS-U Print Document – Item Data  FKKVKP_ISU  FKKVKP  Contract Account Partner- Specific  DFKKKO_ISU  DFKKKO  Header Data in Open Item Accounting Document   Implement FQEVENT R433 (Electronic Document Creation)Create a ‘Z’ function module to implement FQEVENT R433, using the method PREPARE_EDOCUMENTS from the class CL_EDOC_SOURCE in FM. This method utilizes the factory class of eDocument IS-U to get an instance of the eDocument IS-U class. Sample Code:  FUNCTION ZEDOC_ISU_IN_R433 .
*”———————————————————————-
*”*”Local Interface:
*” IMPORTING
*” REFERENCE(X_BUPA) TYPE EKUN_EXT
*” REFERENCE(X_FKKVKP) TYPE FKKVKP
*” REFERENCE(X_PRINTDOC) TYPE ISU21_PRINT_DOC
*” REFERENCE(X_PRINTDOCNO) LIKE ERDK-OPBEL
*” REFERENCE(X_INVOICE_UNIT) TYPE ISU21_INVOICE_UNIT
*” REFERENCE(X_PARAM) TYPE ISU21_INVOICE_PARAM
*” TABLES
*” T_VKK_DOC_ID TYPE ISU21_T_VKK_DOC_ID
*” T_BILL_DOC TYPE ISU2A_T_BILL_DOC
*”———————————————————————-

DATA: lv_active TYPE edoc_active,
lv_msgtyp TYPE symsgty,
lv_bukrs TYPE bukrs,
lv_land1 TYPE land1,
ls_erdk TYPE erdk,
ls_fkkvkp TYPE fkkvkp,
ls_bapiret TYPE bapiret2,
ls_source_data TYPE edoc_src_data_isu_invoice,
ls_t001 TYPE t001,
lt_edocument TYPE edoc_instance_tab,
lo_source_data TYPE REF TO cl_edoc_source,
lo_edocument TYPE REF TO cl_edocument,
lx_error TYPE REF TO cx_edocument,
ld_source_data TYPE REF TO data,
inv_doc LIKE LINE OF t_vkk_doc_id,
fkop LIKE LINE OF inv_doc-vkk_doc-t_fkkop.

FIELD-SYMBOLS: <ls_edocument> TYPE edoc_instance.

FREE: lo_source_data,
lo_edocument.

CLEAR: lv_active,
lv_msgtyp,
lv_bukrs,
ls_erdk,
ls_fkkvkp,
ls_bapiret,
ls_source_data,
ls_t001,
lt_edocument[],
inv_doc,
fkop.

“Print Document Header
ls_erdk = x_printdoc-erdk.

READ TABLE t_vkk_doc_id INTO inv_doc WITH KEY id = ‘A’.
IF sy-subrc = 0.
LOOP AT inv_doc-vkk_doc-t_fkkop INTO fkop
WHERE NOT bukrs IS INITIAL.
lv_bukrs = fkop-bukrs.
EXIT.
ENDLOOP.
IF sy-subrc = 0.
SELECT SINGLE land1
INTO lv_land1
FROM t001
WHERE bukrs = lv_bukrs.
IF sy-subrc EQ 0 AND lv_land1 EQ ‘IN’.
SELECT SINGLE active
INTO lv_active
FROM edocompanyactiv
WHERE bukrs = lv_bukrs
AND source_type = cl_edoc_source_isu_invoice=>gc_src_isu_invoice.
IF lv_active = ‘X’.

ls_fkkvkp = x_fkkvkp.

TRY.
ls_source_data-fkkvkp = ls_fkkvkp.
MOVE-CORRESPONDING inv_doc-vkk_doc-fkkko TO ls_source_data-dfkkko.
SELECT SINGLE *
FROM t001
INTO ls_t001
WHERE bukrs = lv_bukrs.
IF sy-subrc EQ 0.
ls_source_data-t001 = ls_t001.
ls_source_data-source_header-land = ls_t001-land1.
ENDIF.
ls_source_data-source_header-bukrs = lv_bukrs.
ls_source_data-source_header-source_type = cl_edoc_source_isu_invoice=>gc_src_isu_invoice.
ls_source_data-document_header = ls_erdk.
ls_source_data-document_item = x_printdoc-t_erdz.
* Fill source document key
cl_edoc_source_isu_invoice=>pack_key( EXPORTING iv_opbel = ls_erdk-opbel
IMPORTING ev_key = ls_source_data-source_header-source_key ).

GET REFERENCE OF ls_source_data INTO ld_source_data.
lo_source_data = cl_edoc_source_isu_invoice=>create_instance( ld_source_data ).

IF lo_source_data IS BOUND.

lt_edocument = lo_source_data->prepare_edocuments(
iv_update_task = abap_true
iv_hook = abap_true ).
LOOP AT lt_edocument ASSIGNING <ls_edocument>.
IF <ls_edocument>-edocument IS BOUND.
<ls_edocument>-edocument->create_edocument( ).
ENDIF.
ENDLOOP.

ENDIF.
CATCH cx_edocument INTO lx_error.

LOOP AT lx_error->mt_message INTO ls_bapiret.
“Default type Error
lv_msgtyp = ‘E’.
IF lo_edocument IS BOUND.
“eDocument has been created
IF lo_edocument->mv_saved_in_db = abap_true.
lv_msgtyp = ‘I’.
ENDIF.
ENDIF.
MESSAGE ID ls_bapiret-id TYPE lv_msgtyp NUMBER ls_bapiret-number
WITH ls_bapiret-message_v1 ls_bapiret-message_v2
ls_bapiret-message_v3 ls_bapiret-message_v4.
ENDLOOP.

ENDTRY.
ENDIF.
ENDIF.
ENDIF.
ENDIF.

ENDFUNCTION. Implement FQEVENT R428 (Reversal)Similarly, create a ‘Z’ function module to implement FQEVENT R428, using the same method as above for reversal process.Sample Code:  FUNCTION zedoc_isu_in_r428. “#EC CI_FUNCTION
*”———————————————————————-
*”*”Local Interface:
*” IMPORTING
*” REFERENCE(X_REVERSAL_DOC) TYPE ISU21_CANC_DOC OPTIONAL
*” REFERENCE(X_INVOICE_DOC) TYPE ISU21_INVOICE_UNIT OPTIONAL
*” REFERENCE(X_REVERSAL_PARAM) TYPE ISU21_CANC_PARAM OPTIONAL
*” REFERENCE(X_INVOICE_PARAM) TYPE ISU21_INVOICE_PARAM OPTIONAL
*” REFERENCE(X_CALL_ID) TYPE C
*” TABLES
*” XYT_EITR TYPE ISU21_T_EITR
*”———————————————————————-

DATA: lv_bukrs TYPE bukrs,
lv_active TYPE edoc_active,
lv_invopbel TYPE opbel_kk,
lv_msgtyp TYPE symsgty,
ls_erdk TYPE erdk,
ls_fkkvkp TYPE fkkvkp,
ls_bukrs TYPE eitr,
ls_t001 TYPE t001,
ls_erdb TYPE erdb,
ls_dfkkko TYPE dfkkko,
ls_source_data TYPE edoc_src_data_isu_invoice,
ls_bapiret TYPE bapiret2,
lt_erdz TYPE edoc_erdz_tab,
lt_t001z TYPE STANDARD TABLE OF t001z,
lt_edocument TYPE edoc_instance_tab,
lo_source_data TYPE REF TO cl_edoc_source,
lo_edocument TYPE REF TO cl_edocument,
lx_error TYPE REF TO cx_edocument,
ld_source_data TYPE REF TO data.

FIELD-SYMBOLS: <ls_edocument> TYPE edoc_instance.

FREE: lo_source_data,
lo_edocument.

CLEAR: lv_bukrs,
lv_active,
lv_invopbel,
lv_msgtyp,
ls_erdk,
ls_fkkvkp,
ls_bukrs,
ls_t001,
ls_erdb,
ls_dfkkko,
ls_source_data,
ls_bapiret,
lt_erdz[],
lt_t001z[],
lt_edocument[].

* This event should be trigger only for reversal process
IF x_call_id = ‘R’.

LOOP AT x_reversal_doc-t_eitr INTO ls_bukrs
WHERE bukrs IS NOT INITIAL.
lv_bukrs = ls_bukrs-bukrs.
ENDLOOP.

SELECT SINGLE *
FROM t001
INTO ls_t001
WHERE bukrs = lv_bukrs.
IF ls_t001-land1 EQ ‘IN’.

SELECT SINGLE active
INTO lv_active
FROM edocompanyactiv
WHERE bukrs = lv_bukrs
AND source_type = cl_edoc_source_isu_invoice=>gc_src_isu_invoice.
IF lv_active = ‘X’ AND
x_reversal_doc-new_print_doc-erdk-opbel IS NOT INITIAL.

ls_erdk = x_reversal_doc-new_print_doc-erdk.
lt_erdz = x_reversal_doc-new_print_doc-t_erdz.
ls_fkkvkp = x_reversal_doc-acc-fkkvkp.

LOOP AT x_reversal_doc-old_print_doc-t_erdb INTO ls_erdb
WHERE doc_id = ‘A’ OR doc_id = ‘S’.
lv_invopbel = ls_erdb-invopbel.
ENDLOOP.

SELECT SINGLE *
FROM dfkkko
INTO ls_dfkkko
WHERE opbel = lv_invopbel.
IF sy-subrc EQ 0.
ls_source_data-dfkkko = ls_dfkkko.
ENDIF.

SELECT *
FROM t001z
INTO TABLE lt_t001z
WHERE bukrs = lv_bukrs.
IF sy-subrc EQ 0.
ls_source_data-t001z = lt_t001z.
ENDIF.
TRY.

* Source structure mapping
ls_source_data-document_header = ls_erdk.
ls_source_data-document_item = lt_erdz .
ls_source_data-source_header-source_type = cl_edoc_source_isu_invoice=>gc_src_isu_invoice.
ls_source_data-source_header-bukrs = lv_bukrs.
ls_source_data-source_header-land = ls_t001-land1.
ls_source_data-t001 = ls_t001.
ls_source_data-fkkvkp = ls_fkkvkp.
* fill source document key
cl_edoc_source_isu_invoice=>pack_key( EXPORTING iv_opbel = ls_erdk-opbel
IMPORTING ev_key = ls_source_data-source_header-source_key ).

GET REFERENCE OF ls_source_data INTO ld_source_data.
lo_source_data = cl_edoc_source_isu_invoice=>create_instance( ld_source_data ).

IF lo_source_data IS BOUND.

lt_edocument = lo_source_data->prepare_edocuments(
iv_update_task = abap_true
iv_hook = abap_true ).
LOOP AT lt_edocument ASSIGNING <ls_edocument>.
IF <ls_edocument>-edocument IS BOUND.
<ls_edocument>-edocument->create_edocument( ).
ENDIF.
ENDLOOP.

ENDIF.
CATCH cx_edocument INTO lx_error.

LOOP AT lx_error->mt_message INTO ls_bapiret.
“Default type Error
lv_msgtyp = ‘E’.
IF lo_edocument IS BOUND.
“eDocument has been created
IF lo_edocument->mv_saved_in_db = abap_true.
lv_msgtyp = ‘I’.
ENDIF.
ENDIF.
MESSAGE ID ls_bapiret-id TYPE lv_msgtyp NUMBER ls_bapiret-number
WITH ls_bapiret-message_v1 ls_bapiret-message_v2
ls_bapiret-message_v3 ls_bapiret-message_v4.
ENDLOOP.

ENDTRY.
ENDIF.
ENDIF.
ENDIF.

ENDFUNCTION. Create Factory ClassCreate a ‘Z’ factory class to get the instance of eDocument IS-U class by inheriting CL_EDOC_FACTORY class and redefine its method CREATE_EDOC_INSTANCE. Example: ZCL_EDOC_FACTORY_IN_ISUSample Code:   METHOD create_edoc_instances.

DATA: lv_land_iso TYPE edoc_land,
lv_error_txt TYPE string,
ls_source_header TYPE edoc_src_header,
lo_edocument TYPE REF TO zcl_edocument_in_isu.

CLEAR: lv_land_iso,
lv_error_txt,
ls_source_header,
lo_edocument,
et_edocument_obj.

* Country
ls_source_header = io_source->get_header( ).
CALL FUNCTION ‘COUNTRY_CODE_SAP_TO_ISO’
EXPORTING
sap_code = ls_source_header-land
IMPORTING
iso_code = lv_land_iso
EXCEPTIONS
not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE e881(b1) WITH ls_source_header-land INTO lv_error_txt.
ENDIF.
IF lv_land_iso <> ‘IN’.
RETURN.
ENDIF.

CREATE OBJECT lo_edocument
EXPORTING
io_source_data = io_source
iv_update_task = iv_update_task.

APPEND lo_edocument TO et_edocument_obj.

ENDMETHOD.          2. Configure this ‘Z’ eDocument factory class in the view EDOFACTORYV using the transaction SM30.                Example:Source Type  Factory Class  ISU_INVOIC  ‘Z’ factory class name (your factory class that you just created)  Create eDocument ClassCreate a ‘Z’ eDocument class by inheriting CL_EDOCUMENT_IN_EINV class.  Add the CONSTRUCTOR method to your ‘Z’ eDocument class to map the ‘Z’ eDocument IS-U class name to ms_edocument-edocument_class.    Redefine the method DETERMINE_EDOC_TYPE to assign the eDocument type.Use the table TFK003EDOC to configure eDocument type against the accounting document typeExampleCountry/Region Application Area Document Type eDocument Type IN Utility Company FA IN_EINV IN Utility Company ST IN_EINV  Add the class CL_EDOC_PROCESS as ‘Friends’ of ‘Z’ eDocument class. Sample Code:  METHOD determine_edoc_type.

DATA: lv_blart TYPE blart,
ls_tfk003edoc TYPE tfk003edoc.

CLEAR: lv_blart,
ls_tfk003edoc.

IF mo_source->mv_source_type = cl_edoc_source_isu_invoice=>gc_src_isu_invoice.
lv_blart = mo_source->get_blart( ).
* ls_tfk003edoc = me->select_tfk003edoc( iv_land = ms_edocument-land iv_blart = lv_blart ).
DATA: l_applk TYPE tfkfbs-applk.

CLEAR: l_applk,
ls_tfk003edoc.

CALL FUNCTION ‘FKK_GET_APPLICATION’
IMPORTING
e_applk = l_applk
EXCEPTIONS
no_appl_selected = 1
OTHERS = 2.
IF sy-subrc EQ 0.
SELECT SINGLE *
FROM tfk003edoc
INTO ls_tfk003edoc
WHERE land = ms_edocument-land
AND applk = l_applk
AND blart = lv_blart.
ENDIF.
rv_edoc_type = ls_tfk003edoc-edoc_type.
ELSE.
rv_edoc_type = super->determine_edoc_type( ).
ENDIF.
ms_edocument-edoc_type = rv_edoc_type.

determine_edoc_type_global(
CHANGING
cv_edoc_type = rv_edoc_type ).

ENDMETHOD.
METHOD constructor.

super->constructor( io_source_data = io_source_data
iv_edoc_guid = iv_edoc_guid
iv_land = iv_land
iv_generic_badi_filter_adaptor = ‘ISU_INVOIC’
iv_update_task = iv_update_task ).

ms_edocument-land = ‘IN’.
ms_edocument-edocument_class = ‘ZCL_EDOCUMENT_IN_ISU’.

ENDMETHOD.Create Mapping ClassCreate a ‘Z’ mapping class by inheriting CL_EDOC_MAP_IN_EINV class. Example: ZCL_EDOC_MAP_IN_EINV_ISURedefine the method MAP_GEN_EINVR1 of the newly created class to fill the proxy structure with utilities data.Implement the BAdI EDOC_INTERFACE_CONNECTOR (Enhancement Spot – ES_EDOCUMENT) with specific filters. Inherit the class CL_EDOC_INTF_CONN_IN_EINV_AIF and delete the interfaces in ‘Z’ BAdI class. Redefine the method IF_EDOC_INTF_CONN_IMPL~GET_SOURCE_DATA to map the IS-U print document data to rd_source_data.Deactivate the standard BAdI enhancement implementation EI_EDOC_INTF_CONN_IN_EINV_AIF.  Configure your mapping class in the view EDOMAPCLASSDETV using the transaction SM30. Example: eDocument Process Version Interface ID eDocument Type Source Type Mapping Class INEINV 1 IN_EINV_GENERATE_REQ IN_EINV ISU_INVOIC <Your mapping class> INEINV 2 IN_EINV_GENERATE_REQ IN_EINV ISU_INVOIC <Your mapping class> Sample Code for Get Source Data   METHOD if_edoc_intf_conn_impl~get_source_data.

DATA : ls_isu_invoice TYPE edoc_src_data_isu_invoice,
lo_edocument_in TYPE REF TO zcl_edocument_in_isu,
lo_source TYPE REF TO cl_edoc_source,
ls_src_header TYPE edoc_src_header,
ls_source TYPE edoc_in_gen_source,
lv_class_name TYPE edoc_mapping_class.

DATA : lv_doc_header TYPE string,
lv_doc_item TYPE string,
lv_t001 TYPE string,
lv_t001z TYPE string,
lv_fkkvkp TYPE string,
lv_dfkkko TYPE string.

CONSTANTS: lc_document_header TYPE char15 VALUE ‘DOCUMENT_HEADER’.

FIELD-SYMBOLS: <fs_doc_header> TYPE any,
<fs_doc_header1> TYPE any,
<fs_doc_item> TYPE any,
<fs_doc_item1> TYPE any,
<fs_t001> TYPE any,
<fs_t0011> TYPE any,
<fs_t001z> TYPE any,
<fs_t001z1> TYPE any,
<fs_fkkvkp> TYPE any,
<fs_fkkvkp1> TYPE any,
<fs_dfkkko> TYPE any,
<fs_dfkkko1> TYPE any.

FIELD-SYMBOLS: <ls_source> TYPE edoc_in_gen_source.

TRY.
CALL METHOD super->if_edoc_intf_conn_impl~get_source_data
EXPORTING
io_edocument = io_edocument
receiving
rd_source_data = rd_source_data.

IF io_edocument->ms_edocument-source_type = ‘ISU_INVOIC’.
* Retrieve source document and map according to source type
lo_source = io_edocument->get_source( ).
ls_src_header = lo_source->get_header( ).

lo_source->get_data( IMPORTING es_data = ls_isu_invoice ).

lo_edocument_in ?= io_edocument.
ls_source-reference-edoc_guid = lo_edocument_in->ms_edocument-edoc_guid.
ls_source-source_header = ls_src_header.
ls_source-reference-edoc_guid = io_edocument->ms_edocument-edoc_guid.

ASSIGN COMPONENT ‘DOC_HEADER_ISU’ OF STRUCTURE ls_source TO <fs_doc_header1>.
IF <fs_doc_header1> IS ASSIGNED.
lv_doc_header = ‘LS_SOURCE-DOC_HEADER_ISU_HU’.
ASSIGN (lv_doc_header) TO <fs_doc_header>.
ASSIGN COMPONENT lc_document_header OF STRUCTURE ls_isu_invoice TO <fs_doc_header>.
<fs_doc_header1> = <fs_doc_header>.
ENDIF.

ASSIGN COMPONENT ‘DOC_ITEM_ISU’ OF STRUCTURE ls_source TO <fs_doc_item1>.
IF <fs_doc_item1> IS ASSIGNED.
lv_doc_item = ‘LS_SOURCE-DOC_ITEM_ISU_HU’.
ASSIGN (lv_doc_item) TO <fs_doc_item>.
ASSIGN COMPONENT ‘DOCUMENT_ITEM’ OF STRUCTURE ls_isu_invoice TO <fs_doc_item>.
<fs_doc_item1> = <fs_doc_item>.
ENDIF.

ASSIGN COMPONENT ‘FKKVKP’ OF STRUCTURE ls_source TO <fs_fkkvkp1>.
IF <fs_fkkvkp1> IS ASSIGNED.
lv_fkkvkp = ‘LS_SOURCE-FKKVKP’.
ASSIGN (lv_fkkvkp) TO <fs_fkkvkp>.
ASSIGN COMPONENT ‘FKKVKP’ OF STRUCTURE ls_isu_invoice TO <fs_fkkvkp>.
<fs_fkkvkp1> = <fs_fkkvkp>.
ENDIF.

ASSIGN COMPONENT ‘DFKKKO’ OF STRUCTURE ls_source TO <fs_dfkkko1>.
IF <fs_dfkkko1> IS ASSIGNED.
lv_dfkkko = ‘LS_SOURCE-DFKKKO’.
ASSIGN (lv_dfkkko) TO <fs_dfkkko>.
ASSIGN COMPONENT ‘DFKKKO’ OF STRUCTURE ls_isu_invoice TO <fs_dfkkko>.
<fs_dfkkko1> = <fs_dfkkko>.
ENDIF.

CREATE DATA rd_source_data TYPE edoc_in_gen_source.
ASSIGN rd_source_data->* TO <ls_source>.
MOVE-CORRESPONDING ls_source TO <ls_source>.
ENDIF.
CATCH cx_edocument.
ENDTRY.

ENDMETHOD. Maintain the Required CustomizationsActivate company code for ISU_INVOIC source type in the view EDOCOMPANYACTIV for eDocument creation.Example: Company Code  Source Type  Application Active  Your company code  ISU_INVOICE  X  Maintain the view EDOPROCSPINTDETV with the process, process step, eDocument type, source type (ISU_INVOIC).   Example:eDocument Process Version Process Step eDocument Type Source type Proc. Step Variant Interface ID INEINV 1 REQ_CANCEL IN_EINV ISU_INVOIC EWBCANC IN_EINV_CANC_EWB_REQ INEINV 1 REQ_CANCEL IN_EINV ISU_INVOIC EWBCANC IN_EINV_CANC_EWB_REQ INEINV 1 REQ_CANCEL IN_EINV ISU_INVOIC EWBCANC IN_EINV_CANC_EWB_REQ INEINV 1 REQ_CANCEL IN_EINV ISU_INVOIC EWBCANC IN_EINV_CANC_EWB_REQ INEINV 1 GET_DETAIL IN_EINV ISU_INVOIC IRNDOC IN_EINV_GET_DET_DOC_NUM_REQ INEINV 1 GET_DETAIL IN_EINV ISU_INVOIC IRNDOC IN_EINV_GET_DET_DOC_NUM_REQ INEINV 1 GET_DETAIL IN_EINV ISU_INVOIC IRNDOC IN_EINV_GET_DET_DOC_NUM_REQ INEINV 1 GET_DETAIL IN_EINV ISU_INVOIC IRNDOC IN_EINV_GET_DET_DOC_NUM_REQ By following these steps, you can efficiently create electronic documents for invoices in the utilities sector, ensuring compliance and enhancing operational efficiency. Don’t forget to test it thoroughly. We hope this blog post was useful for you! You can leave a comment here or continue browsing our community for more blog posts on SAP Document and Reporting Compliance topics. Looking forward to seeing you here again!    Read More Technology Blog Posts by SAP articles 

#SAP

#SAPTechnologyblog

You May Also Like

More From Author