Monday, November 07, 2016

Linking Change Event to Class

Linking Change Event to Class/Define event for object change

Goal

Material master changes are emailed at EOD to emails.

Functional Overview

  1. Change Document Event sets new Event of Class to process your desired outcome
  2. New Event is linked to Function Module that passes event container elements to Class
  3. Class populates staging table with records desired
  4. Batch program at EOD processes records and notifies users.

Steps in Detail

SWED – Define workflow properties


SWED

 SWEC - Linkage
SWEC
Function Module to pass parameters to Class



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.
   endif.
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.

  clearls_cdhdrlv_elem1lv_elem2.
  refreshlt_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.

  clearls_tab.
  refreshlt_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
tablesmaramarcmaktmarmeordeinalfa1adr6zdt_mat_chg.

*Types
typesbegin 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
datagt_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
datasend_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.

datagv_sender_addr type adr6-smtp_addr.
datagv_sender_name type adr6-smtp_addr.
datalf_sender      type ref to if_sender_bcs.

constantsgc_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.
parametersp_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-optionss_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.

  datalv_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 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.

    clearlv_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.
    cleargs_outputgs_matchg.
  endloop.

endform.                    " BLD_OUTPUT
*&---------------------------------------------------------------------*
*&      Form  EMAIL_OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
form email_output.

  datalv_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.
    clearlv_umrezlv_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.
    cleargs_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( ).

      clearlv_bodylv_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_addressmailto ).

*     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_addressmailto ).

*     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
      cleargv_sent.

      if sent_to_all is initial.
        message i500(sbcomswith mailto.
      else.
        message s022(so).
        gv_sent 'X'.
      endif.

    catch cx_bcs into bcs_exception.
      message i865(sowith 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.

  datals_selopt   type sscr_ass,
        ls_opt_list type sscr_opt_list,
        lt_restrict type sscr_restrict.

  clearls_opt_list.
  ls_opt_list-name          'EQ'.
  ls_opt_list-options-eq    'X'.
  append ls_opt_list to lt_restrict-opt_list_tab.

  clearls_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
 END 

 

2 comments:

Unknown said...

Thank you, this is very valuable information. thank you for your efforts and sharing

Harish Kollipara said...

Can you please provide similar example for COND_A.