
@EndUserText.label : 'Staging Table'
@AbapCatalog.enhancementCategory : #EXTENSIBLE_ANY
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #LIMITED
define table ztest_t_aif {
key mandt : mandt not null;
key field1 : zttsid not null;
key field2 : ztts_item not null;
field3 : ztts_io;
field4 : ztts_pr;
field5 : ztts_pr_itm;
field6 : ztts_asset;
field7 : ztts_po;
field8 : ztts_po_itm;
field9 : ztts_gr;
field10 : ztts_inv;
status : zcomment;
}
@EndUserText.label : 'TEST AIF'
@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
define structure ztest_aif {
field1 : zttsid;
field2 : ztts_item;
field3 : ztts_io;
field4 : ztts_pr;
field5 : ztts_pr_itm;
field6 : ztts_asset;
field7 : ztts_po;
field8 : ztts_po_itm;
field9 : ztts_gr;
field10 : ztts_inv;
status : char50;
}
Source code:
@EndUserText.label : 'Deep Structute'
@AbapCatalog.enhancementCategory : #EXTENSIBLE_CHARACTER
define structure ztest_d_aif {
test : ztest_aif;
}
Define Interface: IF_TEST and assign deep structure created previously & mark check box ‘Move Corresponding structures' (Check node in t-code: /N/AIF/CUST)
FUNCTION ztest_ac_aif
IMPORTING
testrun TYPE c
sending_system TYPE /aif/aif_business_system_key OPTIONAL
CHANGING
data TYPE any ##ADT_PARAMETER_UNTYPED
curr_line TYPE any ##ADT_PARAMETER_UNTYPED
success TYPE /aif/successflag
old_messages TYPE /aif/bal_t_msg
TABLES
return_tab LIKE bapiret2.
DATA: lv_msgty TYPE sy-msgty,
lv_msgv1 TYPE syst_msgv.
REFRESH return_tab.
DATA(ls_aif) = CORRESPONDING ztest_t_aif( curr_line ).
MODIFY ztest_t_aif FROM ls_aif.
IF sy-subrc IS INITIAL.
lv_msgty = 'S'.
IF ls_aif-field9 IS NOT INITIAL AND ls_aif-field10 IS INITIAL.
lv_msgv1 = |Material Document { ls_aif-field9 } posted|.
ELSEIF ls_aif-field9 IS NOT INITIAL AND ls_aif-field10 IS NOT INITIAL.
lv_msgv1 = |Invoice Document { ls_aif-field10 } posted|.
ELSE.
*--prepare messages
return_tab[] =
VALUE #( ( type = |S| id = |/AIF/MES| number = |000| message_v1 = |Internal Order { ls_aif-field3 } created| )
( type = |S| id = |/AIF/MES| number = |000| message_v1 = |Purchase Requsition/Item { ls_aif-field4 } / { ls_aif-field5 } created| )
( type = |S| id = |/AIF/MES| number = |000| message_v1 = |Asset { ls_aif-field6 } posted| ) ).
*
ENDIF.
ELSE.
lv_msgty = 'E'.
IF ls_aif-field9 IS NOT INITIAL AND ls_aif-field10 IS INITIAL.
lv_msgv1 = |Material Document { ls_aif-field9 } not posted|.
ELSEIF ls_aif-field9 IS NOT INITIAL AND ls_aif-field10 IS NOT INITIAL.
lv_msgv1 = |Invoice Document { ls_aif-field10 } not posted|.
ELSE.
*--prepare messages
return_tab[] =
VALUE #( ( type = |E| id = |/AIF/MES| number = |000| message_v1 = |Internal Order { ls_aif-field3 } not created| )
( type = |E| id = |/AIF/MES| number = |000| message_v1 = |Purchase Requsition/Item { ls_aif-field4 } / { ls_aif-field5 } not created| )
( type = |E| id = |/AIF/MES| number = |000| message_v1 = |Asset { ls_aif-field6 } not posted| ) ).
ENDIF.
ENDIF.
*--add message to AIF application log
CALL FUNCTION '/AIF/UTIL_ADD_MSG'
EXPORTING
msgty = lv_msgty
msgid = '/AIF/MES'
msgno = '000'
msgv1 = lv_msgv1
TABLES
return_tab = return_tab.
ENDFUNCTION.
FUNCTION ztest_ac_aif_daemon
IMPORTING
testrun TYPE c
sending_system TYPE /aif/aif_business_system_key OPTIONAL
CHANGING
data TYPE any ##ADT_PARAMETER_UNTYPED
curr_line TYPE any ##ADT_PARAMETER_UNTYPED
success TYPE /aif/successflag
old_messages TYPE /aif/bal_t_msg
TABLES
return_tab LIKE bapiret2.
DATA(ls_curr) = CONV ztest_aif( curr_line ).
TRY.
*--convert from ABAP to JSON to get json long string
**********************************************************************
*--Long string is being converted as PCP protocol only have name value pair
* It would be good to pass internal table/structure in message long string
* Any other way of coversion can also be used e.g XML using CALL TRANSFORMATION etc..
**********************************************************************
DATA(lv_json_output) = /ui2/cl_json=>serialize( data = ls_curr
compress = abap_true pretty_name = /ui2/cl_json=>pretty_mode-camel_case ).
*--check if any daemon already running with name ?
IF zcl_daemon_handler=>check_daemon( daemon_class = 'ZCL_ADF'
daemon_name = |TTS_{ ls_curr-field1 }_{ ls_curr-field2 }| ) EQ abap_false.
*--if not, start daemon with unique name & send payload in xstring format
zcl_daemon_handler=>start_daemon(
EXPORTING i_class_name = 'ZCL_ADF'
i_name = |TTS_{ ls_curr-field1 }_{ ls_curr-field2 }|
*--Pass message(JSON)to daemon
it_pcp_msg = VALUE #( ( name = 'MESSAGE' value = lv_json_output ) ) " Pass message(JSON)to daemon
IMPORTING e_setup_mode = DATA(lv_mode)
e_instance_id = DATA(instance_id) ). "Daemon unqiue instance id
*--if daemon started setup mode will be 1 else start rejected
IF lv_mode EQ 1.
DATA(lv_msgv1) = CONV char50( |Daemon TTS_{ ls_curr-field1 }_{ ls_curr-field2 } started| ).
DATA(lv_msgty) = CONV syst_msgty( 'S').
ELSE.
lv_msgv1 = CONV char50( |Daemon TTS_{ ls_curr-field1 }_{ ls_curr-field2 } start failed| ).
lv_msgty = 'E'.
ENDIF.
ELSE.
lv_msgv1 = CONV char50( |Daemon TTS_{ ls_curr-field1 }_{ ls_curr-field2 } already running...| ).
lv_msgty = CONV syst_msgty( 'S').
*--send message(JSON) to daemon
zcl_daemon_handler=>send_message(
EXPORTING i_daemon_class = CONV #( 'ZCL_ADF' )
i_daemon_name = |TTS_{ ls_curr-field1 }_{ ls_curr-field2 }|
it_pcp_msg = VALUE #( ( name = 'MESSAGE' value = lv_json_output ) ) ).
ENDIF.
Create message type in WE81 and link message & basic type in WE82.
FUNCTION ztest_daemon_outbound_idoc_rfc
IMPORTING
VALUE(i_param) TYPE ztest_d_aif
EXPORTING
VALUE(e_idoc_no) TYPE edi_docnum.
DATA: ls_edidc TYPE edidc,
lt_edidc TYPE STANDARD TABLE OF edidc,
lt_edidd TYPE STANDARD TABLE OF edidd,
ls_segment TYPE ztstseg,
lt_return TYPE STANDARD TABLE OF bapiret2.
*--prepare segment fields
ls_segment = CORRESPONDING #( i_param-test ).
*--prepare IDOC data record
lt_edidd = VALUE #( ( mandt = sy-mandt segnum = '1' segnam = |ZTSTSEG| sdata = ls_segment ) ).
*--prepare idoc control record
ls_edidc = VALUE #( rcvpor = 'TEST' mestyp = |ZTSTMSGTY| idoctp = |ZTSTSEG|
rcvprt = |LS| rcvprn = |TEST | sndprn = |ORDCLNT623| sndprt = |LS| ).
*--trigger Outbound IDOC
CALL FUNCTION 'MASTER_IDOC_DISTRIBUTE'
EXPORTING
master_idoc_control = ls_edidc
TABLES
communication_idoc_control = lt_edidc
master_idoc_data = lt_edidd
EXCEPTIONS
error_in_idoc_control = 1
error_writing_idoc_status = 2
error_in_idoc_data = 3
sending_logical_system_unknown = 4
OTHERS = 5.
IF sy-subrc IS INITIAL.
DATA(ls_test) = CORRESPONDING ztest_t_aif( ls_segment ).
ls_test-status = e_idoc_no = lt_edidc[ 1 ]-docnum.
ls_test-status = |IDOC Number: { e_idoc_no }|.
MODIFY ztest_t_aif FROM ls_test.
*--force release of IDOC lock to avoid status 30
CALL FUNCTION 'DB_COMMIT'.
CALL FUNCTION 'DEQUEUE_ALL'.
COMMIT WORK.
ENDIF.
ENDFUNCTION.
class ZCL_ADF definition
public
inheriting from CL_ABAP_DAEMON_EXT_BASE
final
create public .
public section.
METHODS: if_abap_daemon_extension~on_error REDEFINITION,
if_abap_daemon_extension~on_message REDEFINITION,
if_abap_daemon_extension~on_restart REDEFINITION,
if_abap_daemon_extension~on_server_shutdown REDEFINITION,
if_abap_daemon_extension~on_accept REDEFINITION,
if_abap_daemon_extension~on_start REDEFINITION,
if_abap_daemon_extension~on_stop REDEFINITION,
if_abap_daemon_extension~on_system_shutdown REDEFINITION,
if_abap_daemon_extension~on_before_restart_by_system REDEFINITION.
protected section.
private section.
ENDCLASS.
CLASS ZCL_ADF IMPLEMENTATION.
METHOD if_abap_daemon_extension~on_accept.
TRY.
DATA lv_program_name TYPE program.
lv_program_name = cl_oo_classname_service=>get_classpool_name( 'ZCL_DAEMON_HANDLER' ).
IF i_context_base->get_start_caller_info( )-program = lv_program_name.
e_setup_mode = co_setup_mode-accept.
ELSE.
e_setup_mode = co_setup_mode-reject.
ENDIF.
CATCH cx_abap_daemon_error.
" to do: error handling, e.g. write error log!
e_setup_mode = co_setup_mode-reject.
ENDTRY.
ENDMETHOD.
METHOD IF_ABAP_DAEMON_EXTENSION~ON_BEFORE_RESTART_BY_SYSTEM.
ENDMETHOD.
METHOD if_abap_daemon_extension~on_error.
DATA(lo_call_info) = i_context->get_start_caller_info( ).
DATA: lt_mailsubject TYPE sodocchgi1.
DATA: lt_mailrecipients TYPE STANDARD TABLE OF somlrec90 .
DATA: lt_mailtxt TYPE STANDARD TABLE OF soli.
* Recipients
lt_mailrecipients = VALUE #( ( rec_type = |U| receiver = <put your email ID> ) ).
* Subject.
lt_mailsubject = VALUE #( obj_name = |TEST'| obj_langu = sy-langu obj_descr = |DAEMON: { lo_call_info-name } stopped| ) .
* Mail Contents
lt_mailtxt = VALUE #( ( |DAEMON: { lo_call_info-name } stopped| )
( )
( |REASON CODE: { I_CODE }| )
( |REASON : { I_REASON }| ) ).
* Send Mail
CALL FUNCTION 'SO_NEW_DOCUMENT_SEND_API1'
EXPORTING
document_data = lt_mailsubject
TABLES
object_content = lt_mailtxt
receivers = lt_mailrecipients
EXCEPTIONS
too_many_receivers = 1
document_not_sent = 2
document_type_not_exist = 3
operation_no_authorization = 4
parameter_error = 5
x_error = 6
enqueue_error = 7
OTHERS = 8.
IF sy-subrc EQ 0.
COMMIT WORK.
ENDIF.
ENDMETHOD.
METHOD if_abap_daemon_extension~on_message.
DATA: ls_test_t TYPE ztest_t_aif,
ls_data TYPE ztest_d_aif.
DATA lt_fields TYPE if_ac_message_type_pcp=>tt_pcp_fields.
DATA(lo_parameter) = i_context->get_start_parameter( ).
DATA(lv_text) = lo_parameter->get_text( ).
DATA(lo_call_info) = i_context->get_start_caller_info( ).
DATA(lo_application_para) = i_context->get_application_parameter( ).
DATA(instance_id) = i_context->get_instance_id( ).
*--retrieve PCP Message
i_message->get_fields( CHANGING c_fields = lt_fields ).
*--retrive message
ASSIGN lt_fields[ name = |MESSAGE| ] TO FIELD-SYMBOL(<ls_field>).
IF <ls_field> IS ASSIGNED.
**********************************************************************
*--deserialize from JSON long string to ABAP
**********************************************************************
/ui2/cl_json=>deserialize(
EXPORTING
json = CONV #( <ls_field>-value )
pretty_name = /ui2/cl_json=>pretty_mode-camel_case
CHANGING data = ls_data-test ).
IF ls_data-test IS NOT INITIAL.
ls_test_t = CORRESPONDING #( ls_data-test ).
*--update table
MODIFY ztest_t_aif FROM ls_test_t.
IF sy-subrc IS INITIAL.
COMMIT WORK.
*---trigger outbound IDOC asynchronously
CALL FUNCTION 'ZTEST_DAEMON_OUTBOUND_IDOC_RFC'
STARTING NEW TASK 'NTASK' DESTINATION 'NONE'
EXPORTING
i_param = ls_data.
ENDIF.
ENDIF.
ENDIF.
ENDMETHOD.
METHOD IF_ABAP_DAEMON_EXTENSION~ON_RESTART.
ENDMETHOD.
METHOD IF_ABAP_DAEMON_EXTENSION~ON_SERVER_SHUTDOWN.
ENDMETHOD.
METHOD if_abap_daemon_extension~on_start.
DATA: ls_test_t TYPE ztest_t_aif,
ls_data TYPE ztest_d_aif.
DATA lt_fields TYPE if_ac_message_type_pcp=>tt_pcp_fields.
DATA(lo_parameter) = i_context->get_start_parameter( ).
DATA(lv_text) = lo_parameter->get_text( ).
DATA(lo_call_info) = i_context->get_start_caller_info( ).
DATA(lo_application_para) = i_context->get_application_parameter( ).
DATA(instance_id) = i_context->get_instance_id( ).
*--retrieve pcp MESSAGE
lo_parameter->get_fields( CHANGING c_fields = lt_fields ).
*--retrive message
ASSIGN lt_fields[ name = |MESSAGE| ] TO FIELD-SYMBOL(<ls_field>).
IF <ls_field> IS ASSIGNED.
**********************************************************************
*--deserialize from JSON long string to ABAP
**********************************************************************
/ui2/cl_json=>deserialize(
EXPORTING
json = CONV #( <ls_field>-value )
pretty_name = /ui2/cl_json=>pretty_mode-camel_case
CHANGING data = ls_data-test ).
IF ls_data-test IS NOT INITIAL.
ls_test_t = CORRESPONDING #( ls_data-test ).
*--update table
MODIFY ztest_t_aif FROM ls_test_t.
IF sy-subrc IS INITIAL.
COMMIT WORK.
*---trigger outbound IDOC asynchronously
CALL FUNCTION 'ZTEST_DAEMON_OUTBOUND_IDOC_RFC'
STARTING NEW TASK 'NTASK' DESTINATION 'NONE'
EXPORTING
i_param = ls_data.
ENDIF.
ENDIF.
ENDIF.
ENDMETHOD.
METHOD if_abap_daemon_extension~on_stop.
DATA lt_fields TYPE if_ac_message_type_pcp=>tt_pcp_fields.
DATA(lo_parameter) = i_context->get_start_parameter( ).
DATA(lv_text) = lo_parameter->get_text( ).
i_message->get_fields( CHANGING c_fields = lt_fields ).
DATA(lo_call_info) = i_context->get_start_caller_info( ).
DATA(lo_application_para) = i_context->get_application_parameter( ).
DATA(instance_id) = i_context->get_instance_id( ).
DATA: lt_mailsubject TYPE sodocchgi1.
DATA: lt_mailrecipients TYPE STANDARD TABLE OF somlrec90 .
DATA: lt_mailtxt TYPE STANDARD TABLE OF soli.
* Recipients
lt_mailrecipients = VALUE #( ( rec_type = |U| receiver = <put your email ID> ) ).
* Subject.
lt_mailsubject = VALUE #( obj_name = |TEST'| obj_langu = sy-langu obj_descr = |DAEMON: { lo_call_info-name } stopped| ) .
* Mail Contents
lt_mailtxt = VALUE #( ( |DAEMON: { lo_call_info-name } stopped| ) ).
* Send Mail
CALL FUNCTION 'SO_NEW_DOCUMENT_SEND_API1'
EXPORTING
document_data = lt_mailsubject
TABLES
object_content = lt_mailtxt
receivers = lt_mailrecipients
EXCEPTIONS
too_many_receivers = 1
document_not_sent = 2
document_type_not_exist = 3
operation_no_authorization = 4
parameter_error = 5
x_error = 6
enqueue_error = 7
OTHERS = 8.
IF sy-subrc EQ 0.
COMMIT WORK.
ENDIF.
ENDMETHOD.
METHOD IF_ABAP_DAEMON_EXTENSION~ON_SYSTEM_SHUTDOWN.
ENDMETHOD.
ENDCLASS.
"! <p class="shorttext synchronized" lang="en">Daemon Handler</p>
class ZCL_DAEMON_HANDLER definition
public
final
create public .
public section.
interfaces BI_OBJECT .
interfaces BI_PERSISTENT .
interfaces IF_WORKFLOW .
interfaces BI_EVENT_HANDLER_STATIC .
types:
*--types
BEGIN OF ty_pcp_msg,
i_field TYPE string,
i_value TYPE string,
i_message TYPE string,
END OF ty_pcp_msg .
types:
*--table type
tt_pcp_msg TYPE TABLE OF ty_pcp_msg .
constants:
*--Constant
BEGIN OF co_session_priority,
high TYPE i VALUE 0,
normal TYPE i VALUE 1,
low TYPE i VALUE 2,
END OF co_session_priority .
class-events SEND_MESSAGE_DAEMON
exporting
value(IT_PCP_MESSAGE) type IF_AC_MESSAGE_TYPE_PCP=>TT_PCP_FIELDS .
class-events WF_SEND_MESSAGE_DAEMON
exporting
value(IT_PCP_MESSAGE) type IF_AC_MESSAGE_TYPE_PCP=>TT_PCP_FIELDS .
methods CONSTRUCTOR .
class-methods START_DAEMON
importing
!I_CLASS_NAME type IF_ABAP_DAEMON_TYPES=>TY_ABAP_DAEMON_CLASS_NAME
!I_DESTINATION type IF_ABAP_DAEMON_TYPES=>TY_ABAP_DAEMON_DESTINATION default 'NONE'
!I_NAME type IF_ABAP_DAEMON_TYPES=>TY_ABAP_DAEMON_NAME
value(I_PRIORITY) type IF_ABAP_DAEMON_TYPES=>TY_ABAP_DAEMON_PRIORITY default CO_SESSION_PRIORITY-NORMAL
!IT_PCP_MSG type IF_AC_MESSAGE_TYPE_PCP=>TT_PCP_FIELDS optional
exporting
!E_SETUP_MODE type I
!E_INSTANCE_ID type IF_ABAP_DAEMON_TYPES=>TY_ABAP_DAEMON_INSTANCE_ID
raising
CX_ABAP_DAEMON_ERROR .
class-methods SEND_MESSAGE
importing
!IT_PCP_MSG type IF_AC_MESSAGE_TYPE_PCP=>TT_PCP_FIELDS
!I_DAEMON_CLASS type ABAP_DAEMON_CLASS_NAME
!I_DAEMON_NAME type ABAP_DAEMON_NAME
!I_INSTANCE_ID type ABAP_DAEMON_INSTANCE_ID optional
raising
CX_ABAP_DAEMON_ERROR .
class-methods STOP_DAEMON
importing
!I_DAEMON_CLASS type ABAP_DAEMON_CLASS_NAME
!I_DAEMON_NAME type ABAP_DAEMON_NAME
!I_INSTANCE_ID type ABAP_DAEMON_INSTANCE_ID optional
raising
CX_ABAP_DAEMON_ERROR .
class-methods EVENT_HANDLER
for event SEND_MESSAGE_DAEMON of ZCL_DAEMON_HANDLER .
class-methods RAISE_EVENT
importing
!IT_PCP_MESSAGE type IF_AC_MESSAGE_TYPE_PCP=>TT_PCP_FIELDS .
class-methods CREATE_PCP_MSG
importing
!IT_PCP_MSG type IF_AC_MESSAGE_TYPE_PCP=>TT_PCP_FIELDS optional
returning
value(R_MESSAGE) type ref to IF_AC_MESSAGE_TYPE_PCP
raising
CX_AC_MESSAGE_TYPE_PCP_ERROR .
class-methods GET_DAEMON_INFO
importing
!DAEMON_CLASS type ABAP_DAEMON_CLASS_NAME
!DAEMON_NAME type ABAP_DAEMON_NAME
returning
value(R_INSTANCE_ID) type ABAP_DAEMON_INSTANCE_ID
raising
CX_ABAP_DAEMON_ERROR .
class-methods CHECK_DAEMON
importing
!DAEMON_CLASS type ABAP_DAEMON_CLASS_NAME
!DAEMON_NAME type ABAP_DAEMON_NAME
returning
value(R_BOOLEAN) type ABAP_BOOL .
class-methods RAISE_CLASS_EVENT
importing
value(IT_PCP_MESSAGE) type IF_AC_MESSAGE_TYPE_PCP=>TT_PCP_FIELDS .
class-methods HANDLE_CLASS_EVENT
for event SEND_MESSAGE_DAEMON of ZCL_DAEMON_HANDLER
importing
!IT_PCP_MESSAGE .
PROTECTED SECTION.
private section.
class-data INSTANCE_ID type ABAP_DAEMON_INSTANCE_ID .
class-data DAEMON_HANDLE type ref to IF_ABAP_DAEMON_HANDLE .
ENDCLASS.
CLASS ZCL_DAEMON_HANDLER IMPLEMENTATION.
METHOD bi_event_handler_static~on_event.
DATA: it_pcp_message TYPE if_ac_message_type_pcp=>tt_pcp_fields.
event_container->get( EXPORTING name = 'IT_PCP_MESSAGE' IMPORTING value = it_pcp_message ).
IF zcl_daemon_handler=>check_daemon( daemon_class = CONV #( it_pcp_message[ name = |DAEMON_CLASS| ]-value )
daemon_name = CONV #( it_pcp_message[ name = |DAEMON_NAME| ]-value ) ) EQ abap_false.
zcl_daemon_handler=>start_daemon(
EXPORTING i_class_name = CONV #( it_pcp_message[ name = |DAEMON_CLASS| ]-value )
i_name = CONV #( it_pcp_message[ name = |DAEMON_NAME| ]-value )
IMPORTING e_setup_mode = DATA(lv_mode)
e_instance_id = DATA(instance_id) ).
IF lv_mode EQ 1.
send_message( EXPORTING i_daemon_class = CONV #( it_pcp_message[ name = |DAEMON_CLASS| ]-value )
i_daemon_name = CONV #( it_pcp_message[ name = |DAEMON_NAME| ]-value )
i_instance_id = get_daemon_info( EXPORTING daemon_class = CONV #( it_pcp_message[ name = |DAEMON_CLASS| ]-value )
daemon_name = CONV #( it_pcp_message[ name = |DAEMON_NAME| ]-value ) )
it_pcp_msg = it_pcp_message ).
ENDIF.
ELSE.
send_message( EXPORTING i_daemon_class = CONV #( it_pcp_message[ name = |DAEMON_CLASS| ]-value )
i_daemon_name = CONV #( it_pcp_message[ name = |DAEMON_NAME| ]-value )
i_instance_id = get_daemon_info( EXPORTING daemon_class = CONV #( it_pcp_message[ name = |DAEMON_CLASS| ]-value )
daemon_name = CONV #( it_pcp_message[ name = |DAEMON_NAME| ]-value ) )
it_pcp_msg = it_pcp_message ).
ENDIF.
ENDMETHOD.
METHOD check_daemon.
r_boolean = COND #( WHEN get_daemon_info( EXPORTING daemon_class = daemon_class daemon_name = daemon_name ) IS NOT INITIAL THEN abap_true ).
ENDMETHOD.
METHOD create_pcp_msg.
TRY.
IF it_pcp_msg[] IS SUPPLIED.
DATA(lo_pcp) = cl_ac_message_type_pcp=>create( ).
LOOP AT it_pcp_msg ASSIGNING FIELD-SYMBOL(<ls_pcp_msg>).
*--set PCP field value pair
IF <ls_pcp_msg>-name IS NOT INITIAL AND <ls_pcp_msg>-value IS NOT INITIAL.
lo_pcp->set_field( i_name = <ls_pcp_msg>-name i_value = <ls_pcp_msg>-value ).
ENDIF.
*--set PCP message
* IF <ls_pcp_msg>-i_message IS NOT INITIAL.
* lo_pcp->set_text( <ls_pcp_msg>-i_message ).
* ENDIF.
ENDLOOP.
r_message = lo_pcp.
ENDIF.
CATCH cx_ac_message_type_pcp_error.
ENDTRY.
ENDMETHOD.
method EVENT_HANDLER.
endmethod.
METHOD get_daemon_info.
TRY.
DATA(daemon_info) = cl_abap_daemon_client_manager=>get_daemon_info( daemon_class ).
instance_id = r_instance_id = VALUE #( daemon_info[ name = daemon_name ]-instance_id ).
CATCH cx_root.
clear: instance_id, r_instance_id.
ENDTRY.
ENDMETHOD.
METHOD handle_class_event.
IF zcl_daemon_handler=>check_daemon( daemon_class = CONV #( it_pcp_message[ name = |DAEMON_CLASS| ]-value )
daemon_name = CONV #( it_pcp_message[ name = |DAEMON_NAME| ]-value ) ) EQ abap_false.
zcl_daemon_handler=>start_daemon(
EXPORTING i_class_name = CONV #( it_pcp_message[ name = |DAEMON_CLASS| ]-value )
i_name = CONV #( it_pcp_message[ name = |DAEMON_NAME| ]-value )
IMPORTING e_setup_mode = DATA(lv_mode)
e_instance_id = DATA(instance_id) ).
IF lv_mode EQ 1.
send_message( EXPORTING i_daemon_class = CONV #( it_pcp_message[ name = |DAEMON_CLASS| ]-value )
i_daemon_name = CONV #( it_pcp_message[ name = |DAEMON_NAME| ]-value )
i_instance_id = get_daemon_info( EXPORTING daemon_class = CONV #( it_pcp_message[ name = |DAEMON_CLASS| ]-value )
daemon_name = CONV #( it_pcp_message[ name = |DAEMON_NAME| ]-value ) )
it_pcp_msg = it_pcp_message ).
ENDIF.
ELSE.
send_message( EXPORTING i_daemon_class = CONV #( it_pcp_message[ name = |DAEMON_CLASS| ]-value )
i_daemon_name = CONV #( it_pcp_message[ name = |DAEMON_NAME| ]-value )
i_instance_id = get_daemon_info( EXPORTING daemon_class = CONV #( it_pcp_message[ name = |DAEMON_CLASS| ]-value )
daemon_name = CONV #( it_pcp_message[ name = |DAEMON_NAME| ]-value ) )
it_pcp_msg = it_pcp_message ).
ENDIF.
ENDMETHOD.
METHOD RAISE_CLASS_EVENT.
DATA ls_handler TYPE REF TO zcl_daemon_handler.
SET HANDLER zcl_daemon_handler=>handle_class_event.
RAISE EVENT send_message_daemon
EXPORTING
it_pcp_message = it_pcp_message.
ENDMETHOD.
METHOD raise_event.
TRY.
DATA(lr_container) = cl_swf_evt_event=>get_event_container( EXPORTING
im_objcateg = cl_swf_evt_event=>mc_objcateg_cl
im_objtype = 'ZCL_DAEMON_HANDLER'
im_event = 'WF_SEND_MESSAGE_DAEMON' ).
lr_container->set( name = 'IT_PCP_MESSAGE' value = it_pcp_message ).
CALL METHOD cl_swf_evt_event=>raise
EXPORTING
im_objcateg = cl_swf_evt_event=>mc_objcateg_cl
im_objtype = 'ZCL_DAEMON_HANDLER'
im_event = 'WF_SEND_MESSAGE_DAEMON'
im_objkey = 'WBV'
im_event_container = lr_container.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = abap_true.
* IMPORTING
* RETURN =
CATCH cx_root INTO DATA(lo_err).
MESSAGE lo_err->get_text( ) TYPE 'E'.
ENDTRY.
ENDMETHOD.
METHOD send_message.
IF i_instance_id IS SUPPLIED.
daemon_handle = cl_abap_daemon_client_manager=>attach( i_instance_id ).
ELSE.
daemon_handle = cl_abap_daemon_client_manager=>attach( get_daemon_info( daemon_class = i_daemon_class
daemon_name = i_daemon_name ) ).
ENDIF.
IF daemon_handle IS INITIAL.
RAISE EXCEPTION TYPE cx_abap_daemon_error
EXPORTING
textid = cx_abap_daemon_error=>action_not_permitted.
ENDIF.
TRY.
daemon_handle->send( create_pcp_msg( it_pcp_msg = it_pcp_msg ) ).
CATCH cx_ac_message_type_pcp_error.
"handle exception
ENDTRY.
ENDMETHOD.
METHOD start_daemon.
TRY.
cl_abap_daemon_client_manager=>start(
EXPORTING
i_class_name = i_class_name
i_destination = i_destination
i_name = i_name
i_priority = i_priority
i_parameter = create_pcp_msg( it_pcp_msg = it_pcp_msg )
IMPORTING
e_setup_mode = e_setup_mode
e_instance_id = e_instance_id ).
CATCH cx_root.
ENDTRY.
ENDMETHOD.
METHOD stop_daemon.
TRY.
IF i_instance_id IS SUPPLIED.
cl_abap_daemon_client_manager=>stop( i_instance_id ).
ELSE.
cl_abap_daemon_client_manager=>stop( get_daemon_info( daemon_class = i_daemon_class daemon_name = i_daemon_name ) ).
ENDIF.
CATCH cx_ac_message_type_pcp_error.
"handle exception
ENDTRY.
ENDMETHOD.
ENDCLASS.
*&---------------------------------------------------------------------*
*& Report ZTEST_AIF
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ztest_aif.
TABLES : ztest_t_aif.
INCLUDE <icon>.
DATA: ls_aif TYPE ztest_d_aif,
ls_aif_out TYPE STANDARD TABLE OF ztest_d_aif.
DATA: ok_pushbuttontext TYPE svalbutton-buttontext,
icon_ok_push TYPE icon-name,
returncode TYPE char1,
icon_button_1 LIKE icon-name,
icon_button_2 LIKE icon-name.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
PARAMETERS : p_aif RADIOBUTTON GROUP rb1 DEFAULT 'X' USER-COMMAND cmd,
p_stop RADIOBUTTON GROUP rb1.
SELECTION-SCREEN END OF BLOCK b1.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-002.
PARAMETERS : field1 TYPE zttsid MODIF ID sc1,
field2 TYPE ztts_item MODIF ID sc1.
PARAMETERS: p_dname TYPE abap_daemon_name MODIF ID sc2,
p_dintc TYPE abap_daemon_instance_id MODIF ID sc2.
SELECTION-SCREEN END OF BLOCK b2.
INITIALIZATION.
*--Request number & item
field1 = CONV #( sy-datum ).
field2 = CONV #( sy-uzeit ).
AT SELECTION-SCREEN OUTPUT.
*----------------------------------------------
LOOP AT SCREEN.
IF p_aif IS NOT INITIAL.
IF screen-group1 = |SC1|.
screen-active = |1|.
ENDIF.
IF screen-group1 = |SC2|.
screen-active = |0|.
ENDIF.
ELSE.
IF screen-group1 = |SC1|.
screen-active = |0|.
ENDIF.
IF screen-group1 = |SC2|.
screen-active = |1|.
ENDIF.
ENDIF.
MODIFY SCREEN.
ENDLOOP.
*----------------------------------------------
START-OF-SELECTION.
DATA(lt_components) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_name( |ZTEST_AIF| ) )->components .
IF p_aif IS NOT INITIAL AND
( field1 IS INITIAL OR field2 IS INITIAL ).
MESSAGE 'Fill out all required entry for field1/2' TYPE 'S' DISPLAY LIKE 'E'.
STOP.
ENDIF.
IF p_stop IS NOT INITIAL AND
( p_dname IS INITIAL OR p_dintc IS INITIAL ).
MESSAGE 'Fill either daemon name or daemon instance id' TYPE 'S' DISPLAY LIKE 'E'.
STOP.
ENDIF.
*--prepare aif meesage
IF p_aif IS NOT INITIAL .
CLEAR ls_aif.
ls_aif-test-field1 = field1.
ls_aif-test-field2 = field2.
*--Random Dummy internal order number(Covert INT to CHAR)
ls_aif-test-field3 = |{ CONV char50( cl_abap_random_int=>create( seed = 10000 min = 10000 max = 19999 )->get_next( ) ) WIDTH = 10 ALPHA = IN } |.
*--Random Dummy Purchase Requisition(Covert INT to CHAR)
ls_aif-test-field4 = |{ CONV char50( cl_abap_random_int=>create( seed = 20000 min = 20000 max = 29999 )->get_next( ) ) WIDTH = 10 ALPHA = IN } |.
*--RandomDummy Purchase Requisition Item(Covert INT to CHAR)
ls_aif-test-field5 = |{ CONV char50( cl_abap_random_int=>create( seed = 10 min = 10 max = 999 )->get_next( ) ) WIDTH = 5 ALPHA = IN } |.
*--Random Dummy Asset(Covert INT to CHAR)
ls_aif-test-field6 = |{ CONV char50( cl_abap_random_int=>create( seed = 30000 min = 30000 max = 39999 )->get_next( ) ) WIDTH = 10 ALPHA = IN }|.
*--trigger Inbound AIF
/aif/cl_enabler_xml=>transfer_to_aif( EXPORTING is_any_structure = ls_aif IMPORTING ev_msgguid = DATA(lv_guid) ).
*--prepare pop-up attributes
DATA(popup_title) = CONV char30( |Send Message to Daemon| ).
DATA(first_pushbutton) = CONV svalbutton-buttontext( |VIA BO/WF EVENT| ).
DATA(quickinfo_button_1) = CONV smp_dyntxt-text( |Send Message VIA WF Event| ).
DATA(second_pushbutton) = CONV svalbutton-buttontext( |VIA CLASS EVENT| ).
DATA(quickinfo_button_2) = CONV smp_dyntxt-text( |Send Message VIA Class Event| ).
DATA(quickinfo_ok_push) = CONV smp_dyntxt-text( |Ok| ).
DO.
*--Fields to be displayed in the Pop-up
DATA(lv_index) = sy-index.
CASE lv_index.
WHEN 1.
DATA(lt_fields) = VALUE ty_sval(
( tabname = |ZTEST_T_AIF| fieldname = |FIELD7| value = ztest_t_aif-field7 fieldtext = |Purchase Order| field_obl = abap_true )
( tabname = |ZTEST_T_AIF| fieldname = |FIELD8| value = ztest_t_aif-field8 fieldtext = |PO Item Number| field_obl = abap_true ) ).
WHEN 2.
*--pop-up push button 1 name
first_pushbutton = CONV svalbutton-buttontext( |Trigger I/B AIF- GR| ).
*--pop-up push button 1 quickinfo
quickinfo_button_1 = CONV smp_dyntxt-text( |Trigger Inbound AIF-GR| ).
*--no second button
CLEAR: second_pushbutton, quickinfo_button_2.
REFRESH lt_fields.
*--prepare pop-up screen field
lt_fields = VALUE ty_sval(
( tabname = |ZTEST_T_AIF| fieldname = |FIELD9| value = ztest_t_aif-field9 fieldtext = |Material Document| field_obl = abap_true ) ).
WHEN 3.
*--pop-up push button 1 name
first_pushbutton = CONV svalbutton-buttontext( |Trigger I/B AIF-Invoice| ).
*--pop-up push button 1 quick info
quickinfo_button_1 = CONV smp_dyntxt-text( |Trigger Inbound AIF-Invoice| ).
*--no second button
CLEAR: second_pushbutton, quickinfo_button_2.
REFRESH lt_fields.
*--prepare pop-up screen field
lt_fields = VALUE ty_sval(
( tabname = |ZTEST_T_AIF| fieldname = |FIELD10| value = ztest_t_aif-field10 fieldtext = |Invoice Number| field_obl = abap_true ) ).
WHEN OTHERS.
*--check if daemon still running ?
IF zcl_daemon_handler=>check_daemon( daemon_class = 'ZCL_ADF'
daemon_name = |TTS_{ field1 }_{ field2 }| ) EQ abap_true.
DATA(lv_line) = |Stop Daemon instanace: TTS_{ field1 }_{ field2 } ?|.
*--Information popup
CALL FUNCTION 'POPUP_TO_DISPLAY_TEXT'
EXPORTING
titel = 'Stop Daemon'
textline1 = lv_line.
*--stop daemon
zcl_daemon_handler=>stop_daemon( EXPORTING i_daemon_class = 'ZCL_ADF'
i_daemon_name = |TTS_{ field1 }_{ field2 }| ).
ENDIF.
*--exit from infinite loop.
EXIT.
ENDCASE.
*--screen pop-up for input
CALL FUNCTION 'POPUP_GET_VALUES_USER_BUTTONS'
EXPORTING
popup_title = popup_title
programname = 'ZTEST_AIF'
formname = 'HANDLE_CODE'
ok_pushbuttontext = ok_pushbuttontext
icon_ok_push = icon_ok_push
quickinfo_ok_push = quickinfo_ok_push
first_pushbutton = first_pushbutton
icon_button_1 = icon_button_1
quickinfo_button_1 = quickinfo_button_1
second_pushbutton = second_pushbutton
icon_button_2 = icon_button_2
quickinfo_button_2 = quickinfo_button_2
IMPORTING
returncode = returncode
TABLES
fields = lt_fields.
IF returncode EQ 'A'.
IF zcl_daemon_handler=>check_daemon( EXPORTING daemon_class = 'ZCL_ADF'
daemon_name = |TTS_{ field1 }_{ field2 }| ) EQ abap_true.
lv_line = |Stop Daemon instanace: TTS_{ field1 }_{ field2 } ?|.
*--Information popup
CALL FUNCTION 'POPUP_TO_DISPLAY_TEXT'
EXPORTING
titel = 'Stop Daemon'
textline1 = lv_line.
zcl_daemon_handler=>stop_daemon( EXPORTING i_daemon_class = 'ZCL_ADF'
i_daemon_name = |TTS_{ field1 }_{ field2 }| ).
ENDIF.
*--exit from infinite loop.
EXIT.
ENDIF.
ENDDO.
ELSEIF p_stop IS NOT INITIAL.
*--stop daemon
zcl_daemon_handler=>stop_daemon( EXPORTING i_daemon_class = 'ZCL_ADF'
i_daemon_name = p_dname
i_instance_id = p_dintc ).
ENDIF.
FORM handle_code TABLES fields STRUCTURE sval
USING code
CHANGING error STRUCTURE svale show_popup.
CASE code.
LOOP AT fields ASSIGNING FIELD-SYMBOL(<ls_fields>).
*--dynamically assign screen input value to structure components
ASSIGN COMPONENT line_index( lt_components[ name = <ls_fields>-fieldname ] )
OF STRUCTURE ls_aif-test TO FIELD-SYMBOL(<fs_comp>).
IF <fs_comp> IS ASSIGNED.
<fs_comp> = <ls_fields>-value.
ENDIF.
ENDLOOP.
*--convert from ABAP to JSON to get json long string
**********************************************************************
*--Long string is being converted as PCP protocol only have name value pair
* It would be good to pass internal table/structure in message long string
* Any other way of coversion can also be used e.g XML using CALL TRANSFORMATION etc..
**********************************************************************
DATA(lv_json_output) = /ui2/cl_json=>serialize( data = ls_aif-test
compress = abap_true pretty_name = /ui2/cl_json=>pretty_mode-camel_case ).
WHEN 'COD1'.
IF lv_index EQ 1.
*--Send Message Via WF Event
zcl_daemon_handler=>raise_class_event(
it_pcp_message = VALUE #( ( name = |MESSAGE| value = lv_json_output )
( name = |DAEMON_NAME| value = |TTS_{ field1 }_{ field2 }| )
( name = |DAEMON_CLASS| value = |ZCL_ADF| ) ) ) .
ELSE.
*--trigger Inbound AIF
/aif/cl_enabler_xml=>transfer_to_aif( EXPORTING is_any_structure = ls_aif IMPORTING ev_msgguid = lv_guid ).
ENDIF.
WHEN 'COD2'.
IF lv_index EQ 1.
*--Send Message Via Class Event
zcl_daemon_handler=>raise_class_event(
it_pcp_message = VALUE #( ( name = |MESSAGE| value = lv_json_output )
( name = |DAEMON_NAME| value = |TTS_{ field1 }_{ field2 }| )
( name = |DAEMON_CLASS| value = |ZCL_ADF| ) ) ).
ELSE.
*--trigger Inbound AIF
/aif/cl_enabler_xml=>transfer_to_aif( EXPORTING is_any_structure = ls_aif IMPORTING ev_msgguid = lv_guid ).
ENDIF.
WHEN OTHERS.
*--Do nothing
ENDCASE.
ENDFORM.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
6 | |
5 | |
3 | |
3 | |
3 | |
3 | |
2 | |
2 | |
2 | |
2 |