Linking Change Event to Class/Define event for object change
Goal
Material master changes are emailed at EOD to emails.
Functional Overview
- Change Document Event sets new Event of Class to process your desired outcome
- New Event is linked to Function Module that passes event container elements to Class
- Class populates staging table with records desired
- Batch program at EOD processes records and notifies users.
Steps in Detail
SWED – Define workflow properties
SWED |
SWEC - Linkage
SWEC |
On Change Function Module |
Function Module
ZFM_MM_CHG_DOC_EVENT_CONTAINER
Import
Tables
Code:
function zfm_mm_chg_doc_event_container .
*"----------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(CHANGEDOCUMENT_HEADER) TYPE CDHDR OPTIONAL
*" VALUE(OBJECT_ID) TYPE SIBFLPORB OPTIONAL
*" VALUE(EVENT) TYPE SWECDEXIT-EVENT OPTIONAL
*" VALUE(EVENT_CONTAINER) TYPE REF TO
*" IF_SWF_IFS_PARAMETER_CONTAINER OPTIONAL
*" TABLES
*" CHANGEDOCUMENT_POSITION STRUCTURE CDPOS OPTIONAL
*"---------------------------------------------------------
data:
lo_event_parameters type ref to if_swf_ifs_parameter_container,
lx_root type ref to cx_root,
ls_cdhdr type cdhdr,
lt_cdpos type standard table of cdpos,
lt_elemname type swfdnamtab,
lv_elemname type swfdname.
*
if object_id-catid = swfev_objcateg_cl
and object_id-typeid = 'ZCL_MM_CHD_EVENT'
and changedocument_header-objectclas = 'MATERIAL'.
try.
lo_event_parameters =
cl_swf_evt_event=>get_event_container(
im_objcateg = object_id-catid
im_objtype = object_id-typeid
im_event = event
).
assert lo_event_parameters is bound.
clear: ls_cdhdr.
refresh: lt_cdpos.
* Populate Data for Destination Class
move changedocument_header to ls_cdhdr.
lt_cdpos[] = changedocument_position[].
assert lt_cdpos[] is not initial.
*---- fill event container
lt_elemname = lo_event_parameters->list_names( ).
loop at lt_elemname into lv_elemname.
case lv_elemname.
when 'CHD_DOC_HDR'.
event_container->set(
name = lv_elemname
value = ls_cdhdr
).
when 'CHD_DOC_POS'.
event_container->set(
name = lv_elemname
value = lt_cdpos
).
endcase.
endloop.
catch cx_root into lx_root.
assert lx_root is not bound.
endtry.
endfunction.
Event Creation Limit with Field Restrictions
Link Class to Event
SWETYPV – Type Linkages
SWETYPV |
Details
Class
Example based on SAP : CL_SWF_SLS_TEST_EVENT
Method ON_EVENT
Code
method bi_event_handler_static~on_event.
data:lo_event_parameters type ref to if_swf_ifs_parameter_container,
ls_cdhdr type cdhdr,
lt_cdpos type standard table of cdpos,
ls_cdpos type cdpos,
lx_root type ref to cx_root,
lt_tab type standard table of zdt_mat_chg,
ls_tab type zdt_mat_chg,
lv_elem1 type swfdname,
lv_elem2 type swfdname,
lv_value type char100.
clear: ls_cdhdr, lv_elem1, lv_elem2.
refresh: lt_cdpos.
lv_elem1 = 'CHD_DOC_HDR'.
lv_elem2 = 'CHD_DOC_POS'.
*CDHDR values
try.
event_container->get(
exporting
name = lv_elem1
importing
value = ls_cdhdr
).
catch cx_root into lx_root.
endtry.
*CDPOS values
try.
event_container->get(
exporting
name = lv_elem2
importing
value = lt_cdpos
).
catch cx_root into lx_root.
endtry.
assert lt_cdpos[] is not initial.
clear: ls_tab.
refresh: lt_tab.
ls_tab-mandt = sy-mandt.
ls_tab-material = ls_cdhdr-objectid.
ls_tab-udate = ls_cdhdr-udate.
read table lt_cdpos into ls_cdpos index 1.
if sy-subrc eq 0.
ls_tab-tabname = ls_cdpos-tabname.
ls_tab-tabkey = ls_cdpos-tabkey.
ls_tab-fname = ls_cdpos-fname.
ls_tab-chngind = ls_cdpos-chngind.
ls_tab-value_new = ls_cdpos-value_new.
ls_tab-value_old = ls_cdpos-value_old.
append ls_tab to lt_tab.
if lt_tab[] is not initial.
modify zdt_mat_chg from table lt_tab[].
endif.
endif.
commit work.
endmethod.
Changes Table
Class EVENT CHD_EVENT Parameters
Program to report Changes
ZAB_MM_MATERIAL_CHANGES
* Description: Material Changes Report *
* Note: tvarvc maintained with emails *
report zab_mm_material_changes no standard page heading
line-size 132.
*Tables
tables: mara, marc, makt, marm, eord, eina, lfa1, adr6, zdt_mat_chg.
*Types
types: begin of ty_output,
matnr type matnr,
maktg type maktg,
lifnr type lifnr,
lifnam type name1_gp,
idnlf type idnlf,
lifn2 type lifn2,
supnam type name1_gp,
groes type groes,
umrez type umrez,
oldval type cdfldvalo,
newval type cdfldvaln,
udate type cddatum,
end of ty_output,
begin of ty_matdata,
matnr type matnr,
groes type groes,
maktg type maktg,
end of ty_matdata,
begin of ty_marc,
matnr type matnr,
werks type werks_d,
end of ty_marc,
begin of ty_marm,
matnr type matnr,
umrez type umrez,
end of ty_marm,
begin of ty_eord,
matnr type matnr,
werks type ewerk,
lifnr type elifn,
zzlifn2 type lifn2,
end of ty_eord,
begin of ty_eina,
infnr type infnr,
matnr type matnr,
lifnr type elifn,
idnlf type idnlf,
end of ty_eina,
begin of ty_lfa1,
lifnr type lifnr,
name1 type name1_gp,
end of ty_lfa1.
*Data
data: gt_matchg type standard table of zdt_mat_chg,
gt_output type standard table of ty_output,
gt_matdata type standard table of ty_matdata,
gt_marc type standard table of ty_marc,
gt_lfa1 type standard table of ty_lfa1,
gt_marm type standard table of ty_marm,
gt_eord type standard table of ty_eord,
gt_eina type standard table of ty_eina,
gt_tvarvc type standard table of tvarvc,
gs_matchg type zdt_mat_chg,
gs_output type ty_output,
gs_matdata type ty_matdata,
gs_marc type ty_marc,
gs_lfa1 type ty_lfa1,
gs_marm type ty_marm,
gs_eord type ty_eord,
gs_eina type ty_eina,
gs_tvarvc type tvarvc,
gv_err type char1,
gv_sent type char1.
*Email data
data: send_request type ref to cl_bcs,
document type ref to cl_document_bcs,
recipient type ref to if_recipient_bcs,
bcs_exception type ref to cx_bcs,
mailto type ad_smtpadr,
main_text type bcsy_text,
binary_content type solix_tab,
size type so_obj_len,
sent_to_all type os_boolean.
data: gv_sender_addr type adr6-smtp_addr.
data: gv_sender_name type adr6-smtp_addr.
data: lf_sender type ref to if_sender_bcs.
constants: gc_tab type c value cl_bcs_convert=>gc_tab,
gc_crlf type c value cl_bcs_convert=>gc_crlf.
*Selection screen
selection-screen begin of block b1 with frame title text-001.
parameters: p_werks type werks_d default '1001' obligatory.
selection-screen end of block b1.
selection-screen begin of block b2 with frame title text-002.
select-options: s_mailto for adr6-smtp_addr no intervals.
selection-screen end of block b2.
initialization.
perform modify_selopt.
start-of-selection.
*Get data
perform get_data.
check gv_err is initial.
*Build output
perform bld_output.
end-of-selection.
*Send output
if gt_output[] is not initial.
perform email_output.
endif.
*Message
if gv_err is not initial.
write:/ 'No records selected for processing'.
elseif gv_sent is not initial.
write:/ 'Document sent via email'.
endif.
*&---------------------------------------------------------------------*
*& Form GET_DATA
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
form get_data.
data: lv_tabix type sy-tabix,
lv_vname type rvari_vnam.
*Fetch all material changes
select *
from zdt_mat_chg
into table gt_matchg.
if sy-subrc eq 0.
*Material info
select a~matnr
a~groes
b~maktg
from mara as a inner join
makt as b on a~matnr eq b~matnr
into table gt_matdata
for all entries in gt_matchg
where a~matnr eq gt_matchg-material.
*Plant data
select matnr
werks
from marc
into table gt_marc
for all entries in gt_matchg
where matnr eq gt_matchg-material
and werks eq p_werks.
if sy-subrc eq 0.
*Filter materials based on input plant
loop at gt_matchg into gs_matchg.
lv_tabix = sy-tabix.
read table gt_marc transporting no fields
with key matnr = gs_matchg-material.
if sy-subrc ne 0.
delete gt_matchg index lv_tabix.
endif.
endloop.
endif.
else.
gv_err = 'X'.
endif.
*Fetch relevant material data
if gt_matchg[] is not initial.
*BPC data
select matnr
umrez
from marm
into table gt_marm
for all entries in gt_matchg
where matnr eq gt_matchg-material
and meinh eq 'CS'.
*Sourcing data
select matnr
werks
lifnr
zzlifn2
from eord
into table gt_eord
for all entries in gt_matchg
where matnr eq gt_matchg-material
and werks eq p_werks
and vdatu le sy-datum
and bdatu ge sy-datum
and notkz eq space.
if sy-subrc eq 0.
*Vendor data
select lifnr
name1
from lfa1
into table gt_lfa1
for all entries in gt_eord
where lifnr eq gt_eord-lifnr.
if sy-subrc eq 0.
*Goods supplier data
select lifnr
name1
from lfa1
appending table gt_lfa1
for all entries in gt_eord
where lifnr eq gt_eord-zzlifn2.
endif.
*Info record data
select infnr
matnr
lifnr
idnlf
from eina
into table gt_eina
for all entries in gt_eord
where matnr eq gt_eord-matnr
and lifnr eq gt_eord-lifnr
and loekz eq space.
endif.
clear: lv_vname.
concatenate 'Z_MATCHG_' p_werks into lv_vname.
condense lv_vname.
*Get variant values
select *
from tvarvc
into table gt_tvarvc
where name eq lv_vname
and type eq 'S'.
else.
gv_err = 'X'.
endif.
endform. " GET_DATA
*&---------------------------------------------------------------------*
*& Form BLD_OUTPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
form bld_output.
*Fill output
loop at gt_matchg into gs_matchg.
*Material
gs_output-matnr = gs_matchg-material.
*Material info
read table gt_matdata into gs_matdata
with key matnr = gs_matchg-material.
if sy-subrc eq 0.
gs_output-maktg = gs_matdata-maktg.
gs_output-groes = gs_matdata-groes.
endif.
*Vendor info
read table gt_eord into gs_eord
with key matnr = gs_matchg-material.
if sy-subrc eq 0.
read table gt_lfa1 into gs_lfa1
with key lifnr = gs_eord-lifnr.
if sy-subrc eq 0.
gs_output-lifnr = gs_eord-lifnr.
gs_output-lifnam = gs_lfa1-name1.
endif.
*Goods supplier info
read table gt_lfa1 into gs_lfa1
with key lifnr = gs_eord-zzlifn2.
if sy-subrc eq 0.
gs_output-lifn2 = gs_eord-zzlifn2.
gs_output-supnam = gs_lfa1-name1.
endif.
endif.
*Supplier product #
read table gt_eina into gs_eina
with key matnr = gs_matchg-material.
if sy-subrc eq 0.
gs_output-idnlf = gs_eina-idnlf.
endif.
*BPC
read table gt_marm into gs_marm
with key matnr = gs_matchg-material.
if sy-subrc eq 0.
gs_output-umrez = gs_marm-umrez.
endif.
*Values
gs_output-oldval = gs_matchg-value_old.
gs_output-newval = gs_matchg-value_new.
*Date
gs_output-udate = gs_matchg-udate.
append gs_output to gt_output.
clear: gs_output, gs_matchg.
endloop.
endform. " BLD_OUTPUT
*&---------------------------------------------------------------------*
*& Form EMAIL_OUTPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
form email_output.
data: lv_string type string,
lv_subj type char50,
lv_body type char255,
lv_umrez type char5,
lv_udate type char10.
*Header
concatenate lv_string
'Material' gc_tab
'Description' gc_tab
'Supplier' gc_tab
'Supp. Name' gc_tab
'Supp Product No' gc_tab
'Goods Supplier' gc_tab
'Goods Supp Name' gc_tab
'Size' gc_tab
'Count' gc_tab
'Old UPC/SCC' gc_tab
'New UPC/SCC' gc_tab
'Change Date' gc_crlf
into lv_string.
*Lines
loop at gt_output into gs_output.
clear: lv_umrez, lv_udate.
*Convert BPC
lv_umrez = gs_output-umrez.
condense lv_umrez.
*Convert date
write gs_output-udate to lv_udate using edit mask '__/__/____'.
concatenate lv_string
gs_output-matnr gc_tab
gs_output-maktg gc_tab
gs_output-lifnr gc_tab
gs_output-lifnam gc_tab
gs_output-idnlf gc_tab
gs_output-lifn2 gc_tab
gs_output-supnam gc_tab
gs_output-groes gc_tab
lv_umrez gc_tab
gs_output-oldval gc_tab
gs_output-newval gc_tab
lv_udate gc_crlf
into lv_string.
clear: gs_output.
endloop.
*Convert string to XLS
try.
cl_bcs_convert=>string_to_solix(
exporting
iv_string = lv_string
iv_codepage = '4103'
iv_add_bom = 'X'
importing
et_solix = binary_content
ev_size = size ).
catch cx_bcs.
message e445(so).
endtry.
try.
* -------- create persistent send request ------------------------
send_request = cl_bcs=>create_persistent( ).
clear: lv_body, lv_subj.
concatenate 'Attached is the material changes report for plant' p_werks
into lv_body separated by space.
* -------- create and set document with attachment ---------------
append lv_body to main_text.
*Subject
concatenate 'Material Changes for Plant' p_werks
into lv_subj separated by space.
document = cl_document_bcs=>create_document(
i_type = 'RAW'
i_text = main_text
i_subject = lv_subj ).
* add the spreadsheet as attachment to document object
document->add_attachment(
i_attachment_type = 'xls'
i_attachment_subject = 'MatChg'
i_attachment_size = size
i_att_content_hex = binary_content ).
* add document object to send request
send_request->set_document( document ).
if s_mailto[] is not initial.
loop at s_mailto.
check s_mailto-low is not initial.
* --------- add recipient (e-mail address) -----------------------
* create recipient object
mailto = s_mailto-low.
recipient = cl_cam_address_bcs=>create_internet_address( mailto ).
* add recipient object to send request
send_request->add_recipient( recipient ).
endloop.
else.
loop at gt_tvarvc into gs_tvarvc.
check gs_tvarvc-low is not initial.
* --------- add recipient (e-mail address) -----------------------
* create recipient object
mailto = gs_tvarvc-low.
recipient = cl_cam_address_bcs=>create_internet_address( mailto ).
* add recipient object to send request
send_request->add_recipient( recipient ).
endloop.
endif.
* set sender
gv_sender_addr = 'DoNotReply@company.com'.
try.
* Create Sender object.
lf_sender = cl_cam_address_bcs=>create_internet_address(
i_address_string = gv_sender_addr
i_address_name = gv_sender_name ).
* Declare Sender.
call method send_request->set_sender
exporting
i_sender = lf_sender.
endtry.
* ---------- send document ---------------------------------------
send_request->set_send_immediately( 'X' ).
sent_to_all = send_request->send( i_with_error_screen = 'X' ).
commit work.
*Set flag
clear: gv_sent.
if sent_to_all is initial.
message i500(sbcoms) with mailto.
else.
message s022(so).
gv_sent = 'X'.
endif.
catch cx_bcs into bcs_exception.
message i865(so) with bcs_exception->error_type.
endtry.
*Delete table entries
if gv_sent is not initial.
delete from zdt_mat_chg where udate le sy-datum.
if sy-subrc eq 0.
commit work.
endif.
endif.
endform. " EMAIL_OUTPUT
*&---------------------------------------------------------------------*
*& Form MODIFY_SELOPT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
form modify_selopt.
data: ls_selopt type sscr_ass,
ls_opt_list type sscr_opt_list,
lt_restrict type sscr_restrict.
clear: ls_opt_list.
ls_opt_list-name = 'EQ'.
ls_opt_list-options-eq = 'X'.
append ls_opt_list to lt_restrict-opt_list_tab.
clear: ls_selopt.
ls_selopt-kind = 'S'.
ls_selopt-name = 'S_MAILTO'.
ls_selopt-sg_main = 'I'.
ls_selopt-sg_addy = ' '.
ls_selopt-op_main = 'EQ'.
ls_selopt-op_addy = 'EQ'.
append ls_selopt to lt_restrict-ass_tab.
call function 'SELECT_OPTIONS_RESTRICT'
exporting
restriction = lt_restrict
exceptions
too_late = 1
repeated = 2
selopt_without_options = 5
selopt_without_signs = 6
invalid_sign = 7
empty_option_list = 9
invalid_kind = 10
repeated_kind_a = 11
others = 12.
endform. " MODIFY_SELOPT
2 comments:
Thank you, this is very valuable information. thank you for your efforts and sharing
Can you please provide similar example for COND_A.
Post a Comment