Trigger Floe from Change Events

Floe can be triggered easily from business events in SAP, like changes to master data or documents.

This example walks through the set-up of a single email to provide notifications of changes to a number of different objects.

Details of the changes for the email are taken from the change tables CDHDR and CD POS.

[1] Set up event for change document

In transaction SWEC, configure the event using a business object or class.

Object

Change Object

Business Object

Event

Trigger Event

Customer

DEBI

KNA1

CHANGED

On change

Asset

ANLA

BUS1022

CHANGED

On change

Purchase Order

EINKBELEG

BUS2012

CHANGED

On change

Credit Limit

KLIM

KNA1

CHANGED

On change

Cost Centre

KOSTL

BUS0012

CHANGED

On change

Vendor

KRED

Z_VENDOR

CHANGED

On change

Delivery

LIEFERUNG

LIKP

CHANGED

On change

Material

MATERIAL

Z00MARA

CHANGED

On change

Sales Document

VERKBELEG

BUS2032

CHANGED

On change

Internal Order RKAUFTRAG ZBUS2075 CHANGED On change

 

 

[2] Set up event type linkages.

In transaction SWETYPV, configure a receiver type and function.

Business Object

Event

Function

KNA1

CHANGED

Z_FLOE_FROM_EVENT

BUS1022

CHANGED

Z_FLOE_FROM_EVENT

BUS2012

CHANGED

Z_FLOE_FROM_EVENT

KNA1

CHANGED

Z_FLOE_FROM_EVENT

BUS0012

CHANGED

Z_FLOE_FROM_EVENT

Z_VENDOR

CHANGED

Z_FLOE_FROM_EVENT

LIKP

CHANGED

Z_FLOE_FROM_EVENT

Z00MARA

CHANGED

Z_FLOE_FROM_EVENT

BUS2032

CHANGED

Z_FLOE_FROM_EVENT

ZBUS2075 CHANGED Z_FLOE_FROM_EVENT

 

The Object Type and Event must match those selected in the previous step.  The ‘Linkage Activated’ checkbox must be selected.  In this example we have used the ‘Receiver Type’ field to store the Floe Email Type ‘A003’.

The Receiver Function Module is the function that will be triggered.

[3] Define the Receiver Function Module

The function contains the following logic: 

  • Read data from the container to get the change id,
  • Read change tables CDHDR and CDPOS to get the detail about the change.
  • Perform any additional selection
  • Fill the Floe variables table
  • Call the Floe function

In the sample code we also pass container fields into the Floe variables so that any data from the container can be included in the email.

 

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
FUNCTION z_floe_from_event.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(EVENT) LIKE  SWETYPECOU-EVENT
*"     VALUE(RECTYPE) LIKE  SWETYPECOU-RECTYPE
*"     VALUE(OBJTYPE) LIKE  SWETYPECOU-OBJTYPE
*"     VALUE(OBJKEY) LIKE  SWEINSTCOU-OBJKEY
*"  TABLES
*"      EVENT_CONTAINER STRUCTURE  SWCONT
*"----------------------------------------------------------------------

* Define Floe API tables
  DATA: ls_recs  TYPE /floe/rec_email_s,
        lt_recs  TYPE /floe/rec_email_t,
        ls_vars  TYPE /floe/vars_s,
        lt_vars  TYPE /floe/vars_t,
        lt_vars2 TYPE /floe/vars_t,
        l_etype  TYPE /floe/etype_code,

* Table for container
        ls_data  TYPE swcont,
        lt_data  TYPE TABLE OF swcont.

* Variables for change table selection
  DATA: l_change_num   TYPE cdchangenr,
        l_object_class TYPE cdobjectcl,
        l_object_id    TYPE cdobjectv.

* Table and structure for change details
  TYPES: BEGIN OF ty_cdpos,
          tabname   TYPE tabname,
          fname     TYPE fieldname,
          value_old TYPE cdfldvalo,
          value_new TYPE cdfldvaln,
          label     TYPE string,
         END OF ty_cdpos.

  DATA: lt_cdpos TYPE TABLE OF ty_cdpos,
        ls_cdpos TYPE ty_cdpos,
        l_len TYPE i.

* Variables for email data
  DATA: l_uname         TYPE cdusername,
        l_udate         TYPE cddatum,
        l_utime         TYPE cduzeit,
        l_user_data     TYPE qisrsuser_data.

* Copy import parameters
  lt_data[]  = event_container[].
  l_etype    = rectype.

* Fill variables from container
  LOOP AT lt_data INTO ls_data.
    CASE ls_data-element.
      WHEN 'CD_CHANGENR'.
        l_change_num = ls_data-value.
      WHEN 'CD_OBJECTCLAS'.
        l_object_class = ls_data-value.
      WHEN 'CD_OBJECTID'.
        l_object_id = ls_data-value.
    ENDCASE.
  ENDLOOP.
*
* Select details from Change Header & Item
  SELECT SINGLE username udate utime FROM cdhdr INTO (l_uname, l_udate, l_utime) WHERE
          objectclas = l_object_class AND
          objectid  = l_object_id AND
          changenr = l_change_num.

  SELECT * FROM cdpos INTO CORRESPONDING FIELDS OF TABLE lt_cdpos WHERE
         objectclas = l_object_class   AND
         objectid   = l_object_id      AND
         changenr   = l_change_num     AND
         chngind    =  'U'             AND
         fname     <> 'AEDAT'          AND
         fname     <> 'AENAM'.
*
* Remove insertions
  DELETE lt_cdpos WHERE fname IS INITIAL.
*
* Exit if table is empty.
  DESCRIBE TABLE lt_cdpos LINES l_len.
  IF l_len = 0.
    RETURN.
  ENDIF.
*
* Get Field name texts
  LOOP AT lt_cdpos INTO ls_cdpos.

    CALL FUNCTION 'DDIF_FIELDLABEL_GET'
      EXPORTING
        tabname        = ls_cdpos-tabname
        fieldname      = ls_cdpos-fname
*       LANGU          = SY-LANGU
*       LFIELDNAME     = ' '
      IMPORTING
        label          = ls_cdpos-label
      EXCEPTIONS
        not_found      = 1
        internal_error = 2
        OTHERS         = 3.

    IF sy-subrc = 0.
      MODIFY lt_cdpos FROM ls_cdpos.
    ENDIF.


  ENDLOOP.
*
* Fill Change details to Floe variables table
  CALL METHOD /floe/core=>get_data_from_table
    EXPORTING
      im_table = lt_cdpos
    IMPORTING
      ex_vars  = lt_vars2.
  LOOP AT lt_vars2 INTO ls_vars.
    APPEND ls_vars TO lt_vars.
  ENDLOOP.
*
* Fill Container table to Floe variables table
  CALL METHOD /floe/core=>get_data_from_table
    EXPORTING
      im_table = lt_data
    IMPORTING
      ex_vars  = lt_vars2.
  LOOP AT lt_vars2 INTO ls_vars.
    APPEND ls_vars TO lt_vars.
  ENDLOOP.
*
* Username
  CALL FUNCTION 'ISR_GET_USER_DETAILS'
    EXPORTING
      id_user_id   = l_uname
    CHANGING
      is_user_data = l_user_data.

  CLEAR ls_vars.
  ls_vars-var_code = 'USERNAME'.
  ls_vars-value    = l_user_data-fullname.
  APPEND ls_vars TO lt_vars.

  CLEAR ls_vars.
  ls_vars-var_code = 'USERID'.
  ls_vars-value = l_uname.
  APPEND ls_vars TO lt_vars.
*
* Date and Time
  CLEAR ls_vars.
  ls_vars-var_code = 'DATE'.
  ls_vars-value = l_udate.

  CALL FUNCTION 'CONV_EXIT_LDATE_OUTPUT_LANGU'
    EXPORTING
      input    = ls_vars-value
*     LANGUAGE = SY-LANGU
    IMPORTING
      output   = ls_vars-value.
*
  REPLACE ALL OCCURRENCES OF '.' IN ls_vars-value WITH ''.
  APPEND ls_vars TO lt_vars.
*
  CLEAR ls_vars.
  ls_vars-var_code = 'TIME'.
  CONCATENATE l_utime+0(2) ':' l_utime+2(2) INTO ls_vars-value.
  APPEND ls_vars TO lt_vars.
*
* Object
  CLEAR ls_vars.
  ls_vars-var_code = 'OBJECT'.
  ls_vars-value = l_object_id.
  APPEND ls_vars TO lt_vars.

  CLEAR ls_vars.
  ls_vars-var_code = 'OBJTYPE'.
  ls_vars-value = objtype.
  APPEND ls_vars TO lt_vars.

  CLEAR ls_vars.
  ls_vars-var_code = 'OBJECTTYPE'.

  SELECT SINGLE stext FROM tojtt INTO ls_vars-value WHERE
    name = objtype AND
    language = sy-langu.
  APPEND ls_vars TO lt_vars.

  CLEAR ls_vars.
  ls_vars-var_code = 'OBJECTNAME'.  "This must be filled in the Floe data user-exit.
  APPEND ls_vars TO lt_vars.
*
* Fill Recipient
*  ls_recs-email = 'xx@xxx.com'.  "This must be filled in the Floe recipient user-exit.
*  ls_recs-type = '1'.
*  APPEND ls_recs TO lt_recs.
*
* Call Floe
  CALL FUNCTION '/FLOE/EMAIL_OUT'
    EXPORTING
      im_etype            = l_etype
      im_elang            = 'E'
*     IM_ESUBJECT_LONG    =
*     IM_DOCUMENT         =
      im_rec_emails       = lt_recs
      im_variables        = lt_vars
*     IM_FORM_DATA        =
*     IM_ATTACHMENTS      =
      im_send_immediately = 'X'.
*   IM_IMPORTANCE             = '1'
*   IM_PREVIEW                =
*   IM_NO_COMMIT              =


ENDFUNCTION.

[4] Define the Floe Email Type

Define an email type in the Floe configuration (in this example, A003) and then create content for the notification email in Floe Email Builder.

 

This is a generic email type for all the above types of changes. (Import the demo email package: FLOE_DM4_800_A003(Encoding=4103).floe )

Specific emails could be designed for particular types of document changes.

[5] Add the Email Data User-Exit

Use the email data user-exit to format the object id (remove leading zeros) and to fill the object name based on the object type.

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
METHOD email_data.
*---------------------------------------------------------------------------*
*                  EMAIL DATA USER-EXIT                                     *
*---------------------------------------------------------------------------*
* This user-exit allows the manipulation of data which will be used to      *
* substitute the relevant placeholders inside the email body                *
*---------------------------------------------------------------------------*
* Data is available in this userexit as follows:
*
*   im_etype            Email Type
*   im_elang            Communication language used in the email - this will
*                       determine the content of the html blocks
*   im_document         External Document Reference
*   ch_variables        Table of variables to be manipulated - fields
*                       include the variable name, value, row number and
*                       parent row number in the case of nested repeating
*                       variable
*---------------------------------------------------------------------------*
* Sample code start >>>>>
*
* Sample Code End >>>>>>
*---------------------------------------------------------------------------*
*                      <<< Start of Customer Code >>>                       *
*---------------------------------------------------------------------------*
  DATA: ls_vars      TYPE /floe/vars_s,
        lt_vars      TYPE /floe/vars_t,
        l_objtype    TYPE swo_objtyp,
        l_object     TYPE swo_typeid,
        l_objectname TYPE string.

  DATA:  l_customer   TYPE kunnr,
         l_vendor     TYPE lifnr,
         l_name1      TYPE name1,
         l_contarea   TYPE kokrs,
         l_costcenter TYPE kostl,
         l_material   TYPE maktx,
         l_compcode   TYPE bukrs,
         l_subnum     TYPE anln2,
         l_asset      TYPE anln1.

* Fill OBJECTNAME based on the object type.

  READ TABLE ch_variables WITH KEY var_code = 'OBJTYPE' INTO ls_vars.
  l_objtype = ls_vars-value.

  READ TABLE ch_variables WITH KEY var_code = 'OBJECT' INTO ls_vars.
  l_object = ls_vars-value.

  CASE l_objtype.

    WHEN 'KNA1'.
      "CUSTOMER: Remove leading zeros
      SHIFT ls_vars-value LEFT DELETING LEADING '0'.
      MODIFY ch_variables FROM ls_vars INDEX sy-tabix.
      "Get customer name
      l_customer = l_object.
      SELECT SINGLE name1 FROM kna1 INTO l_objectname WHERE kunnr EQ l_customer.

    WHEN 'Z_VENDOR'.
      "VENDOR: Remove leading zeros
      SHIFT ls_vars-value LEFT DELETING LEADING '0'.
      MODIFY ch_variables FROM ls_vars INDEX sy-tabix.
      "Get vendor name
      l_vendor = l_object.
      SELECT SINGLE name1 FROM lfa1 INTO l_objectname WHERE lifnr EQ l_vendor.

    WHEN 'BUS1022'.
      "ASSET: Remove company code and subnumber, and leading zeros.
      ls_vars-value = l_object+4(12).
      SHIFT ls_vars-value LEFT DELETING LEADING '0'.
      MODIFY ch_variables FROM ls_vars INDEX sy-tabix.
      "Get asset name
      l_compcode = l_object+0(4).
      l_subnum = l_object+16(4).
      l_asset = l_object+4(12).

      SELECT SINGLE txt50 FROM  anla INTO l_objectname
             WHERE  bukrs  = l_compcode
             AND    anln1  = l_asset
             AND    anln2  = l_subnum.

    WHEN 'BUS0012'.
      "COST CENTER: Remove controlling area
      SHIFT ls_vars-value LEFT BY 4 PLACES.
      MODIFY ch_variables FROM ls_vars INDEX sy-tabix.
      "Get cost center name
      l_contarea = l_object+0(4).
      l_costcenter = l_object+4(10).

      SELECT  ktext FROM cskt UP TO 1 ROWS INTO l_objectname WHERE
               spras  = sy-langu
        AND    kokrs  = l_contarea
        AND    kostl  = l_costcenter
        AND    datbi  GT sy-datum
        ORDER BY datbi.

      ENDSELECT.

    WHEN 'Z00MARA'.
      "MATERIAL: Remove leading zeros
      SHIFT ls_vars-value LEFT DELETING LEADING '0'.
      MODIFY ch_variables FROM ls_vars INDEX sy-tabix.
      "Get material description
      l_material = l_object.
      SELECT SINGLE maktx FROM makt INTO l_objectname WHERE
               matnr EQ l_material
        AND    spras EQ sy-langu.


* Add more as required...

    when others.
*    WHEN 'LIKP' or 'BUS2032' or 'ZBUS2075'.
      " Remove leading zeros
      SHIFT ls_vars-value LEFT DELETING LEADING '0'.
      MODIFY ch_variables FROM ls_vars INDEX sy-tabix.

  ENDCASE.

  READ TABLE ch_variables WITH KEY var_code = 'OBJECTNAME' INTO ls_vars.
  ls_vars-value = l_objectname.
  MODIFY ch_variables FROM ls_vars INDEX sy-tabix.

*---------------------------------------------------------------------------*
*                      <<< End of Customer Code >>>                         *
*---------------------------------------------------------------------------*
ENDMETHOD.

EXAMPLES OF CHANGE NOTIFICATIONS