Custom mass correspondence program

This example shows how to build a custom trigger program to send an email to a list of vendors.

In this example we show how Floe can be used to generate DYNAMIC content, so that when an email is sent to a list, different recipients get different content.

[1] Define the trigger program

In this example we started by copying the delivered program /FLOE/MASS_CORRESP_TRIGGER.

Then we changed the selection options to include vendor master fields, and added in a selection based on those fields.

Then we loop around the table and call Floe for each record that has an email address.

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:
*&---------------------------------------------------------------------*
*& Report  z_supplier_email
*&
*----------------------------------------------------------------------*
* FLOE: Report to Trigger Mass Correspondence Email                    *
*----------------------------------------------------------------------*
* Sample program to trigger mass output to suppliers                   *
*----------------------------------------------------------------------*
REPORT  z_supplier_email.
*
TABLES: lfa1, lfb1, lfm1.
*
*
TYPES: BEGIN OF ty_vendor_list,
         lifnr TYPE lifnr,
         name1 TYPE name1,
         adrnr TYPE adrnr,
         email TYPE ad_smtpadr,
         spras TYPE spras,
         bukrs TYPE bukrs,
         ekorg TYPE ekorg,
         lfabc TYPE lfabc,
         zsabe TYPE dzsabe_k,
       END OF ty_vendor_list.
*
DATA: ls_vendor_list TYPE ty_vendor_list,
      lt_vendor_list TYPE TABLE OF ty_vendor_list,
      l_lifnr        TYPE lifnr.
*
DATA: lt_rec_email  TYPE /floe/rec_email_t,
      ls_rec_email  TYPE /floe/rec_email_s,
      lt_mess       TYPE bapiret2_t,
      ls_mess       TYPE bapiret2,
      lv_subrc      TYPE sysubrc,
      lv_importance TYPE /floe/importance,
      lv_message    TYPE string,
      lt_vars       TYPE /floe/vars_t,
      lv_eid        TYPE /floe/eid,
      lt_suc_mess   TYPE TABLE OF string,
      lv_error      TYPE flag.
*
SELECTION-SCREEN BEGIN OF BLOCK c WITH FRAME TITLE text-015.
SELECTION-SCREEN SKIP 1.
SELECT-OPTIONS: s_lifnr FOR lfa1-lifnr,
                s_land1 FOR lfa1-land1,
                s_bukrs FOR lfb1-bukrs,
                s_ekorg FOR lfm1-ekorg.
SELECTION-SCREEN END OF BLOCK c.

SELECTION-SCREEN SKIP 1.

SELECTION-SCREEN BEGIN OF BLOCK a WITH FRAME TITLE text-001.
SELECTION-SCREEN SKIP 1.
PARAMETERS: p_etype TYPE /floe/etype_code MATCHCODE OBJECT /floe/etype OBLIGATORY,
            p_elang TYPE /floe/elang,
            p_doc   TYPE /floe/doc_ref.
SELECTION-SCREEN END OF BLOCK a.

SELECTION-SCREEN SKIP 1.

SELECTION-SCREEN BEGIN OF BLOCK b WITH FRAME TITLE text-007.
SELECTION-SCREEN SKIP 1.
PARAMETERS: p_send  TYPE /floe/send_immediately.
SELECTION-SCREEN SKIP 2.
SELECTION-SCREEN COMMENT 01(79) text-006.
PARAMETERS: p_im_l  RADIOBUTTON GROUP gr1,
            p_im_n  RADIOBUTTON GROUP gr1 DEFAULT 'X',
            p_im_h  RADIOBUTTON GROUP gr1.
SELECTION-SCREEN END OF BLOCK b.
*
INITIALIZATION.
*
  p_elang = sy-langu.
*
START-OF-SELECTION.

* Get vendor list.
*
  SELECT lifnr name1 adrnr spras FROM lfa1 INTO CORRESPONDING FIELDS OF TABLE lt_vendor_list
    WHERE lifnr IN s_lifnr
    AND   land1 IN s_land1.
*
  LOOP AT lt_vendor_list INTO ls_vendor_list.
*
    SELECT SINGLE bukrs zsabe INTO (ls_vendor_list-bukrs,ls_vendor_list-zsabe) FROM lfb1
      WHERE lifnr EQ ls_vendor_list-lifnr
      AND   bukrs IN s_bukrs.
    IF sy-subrc NE 0.
      DELETE lt_vendor_list.
    ELSE.
      MODIFY lt_vendor_list FROM ls_vendor_list.
*
      SELECT SINGLE ekorg lfabc INTO (ls_vendor_list-ekorg, ls_vendor_list-lfabc) FROM lfm1
        WHERE lifnr EQ ls_vendor_list-lifnr
        AND   ekorg IN s_ekorg.
      IF sy-subrc NE 0.
        DELETE lt_vendor_list.
      ELSE.
*
        SELECT SINGLE smtp_addr FROM adr6 INTO ls_vendor_list-email
          WHERE addrnumber = ls_vendor_list-adrnr.
        MODIFY lt_vendor_list FROM ls_vendor_list.
*
      ENDIF.
    ENDIF.

  ENDLOOP.

END-OF-SELECTION.
*
* Map the importance radio-button
*
  IF p_im_l IS NOT INITIAL.
    lv_importance = '0'.
  ELSEIF p_im_n IS NOT INITIAL.
    lv_importance = '1'.
  ELSE.
    lv_importance = '2'.
  ENDIF.
*
  LOOP AT lt_vendor_list INTO ls_vendor_list WHERE email IS NOT INITIAL.

* Fill recipient
*
    CLEAR lt_rec_email.
    ls_rec_email-email = ls_vendor_list-email.
    ls_rec_email-type = '1'.
    APPEND ls_rec_email TO lt_rec_email.

* Fill communication language.
    IF ls_vendor_list-spras IS INITIAL.
      ls_vendor_list-spras = p_elang.
    ENDIF.

* Fill Floe variables.
    CALL METHOD /floe/core=>get_data_from_structure
      EXPORTING
        im_structure = ls_vendor_list
      IMPORTING
        ex_vars      = lt_vars.

*
* Invoke Floe
*
    CALL FUNCTION '/FLOE/EMAIL_OUT'
      EXPORTING
        im_etype            = p_etype
        im_elang            = ls_vendor_list-spras
        im_document         = p_doc
        im_rec_emails       = lt_rec_email
        im_variables        = lt_vars
        im_send_immediately = p_send
        im_importance       = lv_importance
      IMPORTING
        ex_subrc            = lv_subrc
        ex_mess             = lt_mess
        ex_eid              = lv_eid.
*
* Report result
*
    FORMAT INTENSIFIED OFF.
    IF lv_subrc IS INITIAL.
*
      CONCATENATE: 'Email'(010) lv_eid 'successfully sent to'(012) ls_rec_email-email INTO lv_message SEPARATED BY space.
      APPEND lv_message TO lt_suc_mess.
*
    ELSE.
*
      IF lv_error IS INITIAL.
        SKIP 1.
        WRITE:/ 'The following errors occured:'(013).
        ULINE.
      ENDIF.
*
      lv_error = 'X'.
      CONCATENATE: 'Error while sending email to'(011) ls_rec_email-email INTO lv_message SEPARATED BY space.
      WRITE:/ lv_message.
*
      IF lt_mess IS NOT INITIAL.
*
        FORMAT INTENSIFIED ON.
        WRITE:/ 'Type'(004), 'Message'(005).
        FORMAT INTENSIFIED OFF.
        LOOP AT lt_mess INTO ls_mess.
          WRITE:/ ls_mess-type    UNDER text-004,
                  ls_mess-message UNDER text-005.
        ENDLOOP.
*
      ENDIF.
      SKIP 1.
    ENDIF.
*
  ENDLOOP.
*
  IF lt_suc_mess IS NOT INITIAL.
*
    SKIP 1.
    WRITE:/ 'The following emails were successfully sent:'(014).
    ULINE.
*
    LOOP AT lt_suc_mess INTO lv_message.
      WRITE:/ lv_message.
    ENDLOOP.
*
  ENDIF.

  SKIP 1.
  LOOP AT lt_vendor_list INTO ls_vendor_list WHERE email IS INITIAL.
    WRITE:/ 'No email address found for vendor ', ls_vendor_list-lifnr.
  ENDLOOP.

Download: z_supplier_email.txt

[2] Build the email type

Download the Floe file: FLOE_DM4_800_SL01(Encoding=4103).floe

[3] Add library blocks for alternative content

Download library block: FLOE_DM4_800_FLOE~DM4~0000000071(Encoding=4103).floe

[4] Add userexits

Email Data User-exit

Here we add the FNAME field

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
  DATA: ls_vars TYPE /floe/vars_s,
        lt_vars TYPE /floe/vars_t.


*---------------------------------------------------------------------------*
* Add FNAME variable and fill with clerk's name if available

  READ TABLE ch_variables WITH KEY var_code = 'ZSABE' INTO ls_vars.
  IF ls_vars-value IS INITIAL.
    ls_vars-value = 'valued partner'.
  ENDIF.

  ls_vars-var_code = 'FNAME'.
  APPEND ls_vars TO ch_variables.

Email Recipient User-exit

Here we change the communication language if the email template does not exist in the vendor language

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
* Check the email type exists in the communication language,
* otherwise revert to default language.

  DATA: lv_default_language TYPE /floe/default_language,
        ls_etypecl          type /floe/etypecl.

  SELECT SINGLE default_language FROM /floe/settings INTO lv_default_language
    WHERE sid EQ sy-sysid.

  SELECT SINGLE * FROM /floe/etypecl into ls_etypecl
    WHERE etype EQ im_etype
    AND elang EQ ch_elang.

  IF sy-subrc NE 0.
    ch_elang =  lv_default_language.
  ENDIF.

Block Determination User-exit

Here we determine the alternative content based on the purchase organisation, and remove another block based on the ABC indicator

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
  DATA: ls_vars TYPE /floe/vars_s,
        ls_hblock TYPE /floe/hblock_list_s.

*---------------------------------------------------------------------------*
* Change the header block with logo based on the Purchase Organisation
*
  READ TABLE im_variables WITH KEY var_code = 'EKORG' INTO ls_vars.

  IF ls_vars-value = '0005'.
    READ TABLE ch_hblock_list WITH KEY hblock = 'FLOE~DM4~0000000072' INTO ls_hblock.
    ls_hblock-hblock = 'FLOE~DM4~0000000071'.
    MODIFY ch_hblock_list FROM ls_hblock INDEX sy-tabix.
  ENDIF.

*---------------------------------------------------------------------------*
* Remove the partner summit invitation based on ABC indicator
*
  READ TABLE im_variables WITH KEY var_code = 'LFABC' INTO ls_vars.

  IF ls_vars-value NE 'A'.
    READ TABLE ch_hblock_list WITH KEY hblock = 'FLOE~DM4~0000000076' INTO ls_hblock.
    DELETE ch_hblock_list INDEX sy-tabix.
  ENDIF.

[5] Test the program

The Emails arrive with different content based on the vendor data...