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