Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple PDF attachment using CL_BCS

Former Member
0 Kudos

Hello Experts,

I have a requirement to send Multiple Invoices (PDF attachment) in one email.

i.e.,  If a customer has 3 Invoices; then one email with 3 attachment should be sent.

My code is working for 1 attachment. It is sending 3 separate emails.

I searched in the Forum; found few threads related to FM's and not related to CL_BCS.

Here's my code:

* Attach PDF Invoice in the mail

  DATA: lv_adrnr   TYPE kna1-adrnr,

        lv_name1   TYPE kna1-name1,

        l_sub      TYPE so_obj_des,

        l_invoice  TYPE vbeln_vf,

        p_receiver TYPE so_recname.

  DATA:

   lo_send_request TYPE REF TO cl_bcs ,

   lo_document     TYPE REF TO cl_document_bcs,

   lo_sender       TYPE REF TO if_sender_bcs  ,

   lo_recipient    TYPE REF TO if_recipient_bcs ,

   lt_message_body TYPE bcsy_text ,

   lx_document_bcs TYPE REF TO cx_document_bcs ,

   lv_send         TYPE ad_smtpadr,

   lv_sent_to_all  TYPE os_boolean,

   w_subject(50)   TYPE c.

*The OTF contents are  converted to PDF Format (XSTRING)

  CALL FUNCTION 'CONVERT_OTF'

    EXPORTING

      format                = c_pdf

      max_linewidth         = 132

    IMPORTING

      bin_filesize          = w_bin_size

      bin_file              = w_pdf_xstring

    TABLES

      otf                   = t_datab[]

      lines                 = t_line[]

    EXCEPTIONS

      err_max_linewidth     = 1

      err_format            = 2

      err_conv_not_possible = 3

      err_bad_otf           = 4

      OTHERS                = 5.

  IF sy-subrc <> 0.

    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno

            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

  ENDIF.

* XSTRING format is then converted to Binary Format (SOLIX_TAB) to use in the attachment mail

  CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'

    EXPORTING

      buffer     = w_pdf_xstring

    TABLES

      binary_tab = g_objcont.

  CLASS cl_bcs DEFINITION LOAD.

  SELECT SINGLE adrnr INTO lv_adrnr

     FROM kna1

    WHERE kunnr = nast-parnr.

  IF sy-subrc EQ 0.

    SELECT SINGLE smtp_addr INTO lv_send

      FROM adr6

      WHERE addrnumber = lv_adrnr.

    IF sy-subrc NE 0.

      MESSAGE e999(z1) WITH 'Email id is not updated for customer: ' nast-objky.

    ENDIF.

  ENDIF.

*  "create send request

  lo_send_request = cl_bcs=>create_persistent( ).

* Fetch Name of the Customer

  SELECT SINGLE name1 INTO lv_name1

     FROM kna1

    WHERE kunnr = nast-parnr.

  CONCATENATE lv_name1 ',' INTO lv_name1.

  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'

    EXPORTING

      input  = nast-objky

    IMPORTING

      output = l_invoice.

* Create message body and name of the attachment

  APPEND lv_name1 TO lt_message_body.

  APPEND INITIAL LINE TO lt_message_body.

  APPEND 'Please find the attached Invoice.' TO lt_message_body.

  APPEND l_invoice TO lt_message_body.

  APPEND INITIAL LINE TO lt_message_body.

  APPEND 'This is a system generated email. Please DO NOT REPLY to this email.' TO lt_message_body.

  APPEND INITIAL LINE TO lt_message_body.

  APPEND 'Thank You!' TO lt_message_body.

  CONCATENATE 'Invoice ' nast-objky INTO w_subject.

  CONCATENATE 'Customer Invoice :' l_invoice INTO l_sub.

* Email Body

  lo_document = cl_document_bcs=>create_document(

                                i_type = 'RAW'

                                i_text = lt_message_body

                                i_subject = l_sub ).

* Add attachment

  TRY.

      CALL METHOD lo_document->add_attachment

        EXPORTING

          i_attachment_type    = 'PDF'

          i_attachment_subject = w_subject

          i_att_content_hex    = g_objcont.

    CATCH cx_document_bcs INTO lx_document_bcs.

  ENDTRY.

* Pass the document to send request

  CALL METHOD lo_send_request->set_document( lo_document ).

*  Create sender / Set sender

  lo_sender = cl_sapuser_bcs=>create( sy-uname ).

* Add sender to send request

  CALL METHOD lo_send_request->set_sender

    EXPORTING

      i_sender = lo_sender.

* Create recipient

  lo_recipient = cl_cam_address_bcs=>create_internet_address( lv_send ).

*Set recipient

  CALL METHOD lo_send_request->add_recipient

    EXPORTING

      i_recipient = lo_recipient

      i_express   = 'X'.

* Set send immediately

  lo_send_request->set_send_immediately( 'X' ).

* Send email

  lo_send_request->send(

   EXPORTING

   i_with_error_screen = 'X'

   RECEIVING

   result = lv_sent_to_all ).

  IF sy-subrc EQ space.

    MESSAGE 'Mail sent successfully.' TYPE 'S'.

  ELSE.

    MESSAGE 'Error sending Email' TYPE 'E'.

    ROLLBACK WORK.

  ENDIF.

Please advise.

Thanks & Regards,
Sowmya

1 ACCEPTED SOLUTION

Former Member
0 Kudos

Hello Experts,

We are using Program RV60SBT1 for creating Invoices in background.

The driver program processes one Invoice at a time which is coming from RV60SBT1.

Z Output Type is assigned to the Driver program / Routine.

The requirement with the Customer Invoice emailing is:

Send Multiple Invoice attachment in one email if the Customer is having multiple Invoices.

The driver Program gets NAST data - one record at a particular time.

Whenever the driver Program finds 'SEND()' Method, the email will be sent by attaching one Invoice.

I'm not getting any idea on how multiple Invoices can be attached in one email.

Please do suggest.

Thanks & Regards,
Sowmya

21 REPLIES 21

former_member212002
Active Contributor
0 Kudos

This message was moderated.

FredericGirod
Active Contributor
0 Kudos

Hi Sowmya,

you only have to use several times the method :

      CALL METHOD obj_doc->add_attachment

        EXPORTING

          i_attachment_type    = l_attachement_type

          i_attachment_subject = w_file

          i_attachment_size    = l_lenth

          i_att_content_hex    = it_contentx.

Regards

Fred

rosenberg_eitan
Active Contributor
0 Kudos

Former Member
0 Kudos

Hello Experts,

We are using Program RV60SBT1 for creating Invoices in background.

The driver program processes one Invoice at a time which is coming from RV60SBT1.

Z Output Type is assigned to the Driver program / Routine.

The requirement with the Customer Invoice emailing is:

Send Multiple Invoice attachment in one email if the Customer is having multiple Invoices.

The driver Program gets NAST data - one record at a particular time.

Whenever the driver Program finds 'SEND()' Method, the email will be sent by attaching one Invoice.

I'm not getting any idea on how multiple Invoices can be attached in one email.

Please do suggest.

Thanks & Regards,
Sowmya

0 Kudos

Hi Sowmya

Since every  output type gets triggered when you create an invoice. But since you need to send mulltiple attachement of different invoices for same customer you can do as follow.

You can create a custom report which will take invoices and customer as input and you can add multiple attachment in it.  Initially in order to recoganize for which inovices mail has to be sent you can save the list in a custom table.

Your program will run once or twice a day in background to send the attachments.

Another way out is you check NAST table for the output type related to invoices which got triggered in one day and let your program create attachements for the same and send email

Nabheet

0 Kudos

Hi Sowmya,

you have to copy / used the transaction VF31, this is the trans. to send invoice.

Second point, you have to not print/send invoice immediately (4) you have to set at transaction request (3 I think)

maybe I have an example of code.

regards

Fred

0 Kudos

Thanks Frederic.

But I've to send an email as soon as the Invoice is created.

In Production, users are using RV60SBT1 Program that is scheduled in background.

Which Table can I use to LOOP in my driver program?

Thanks & Regards,
Sowmya

0 Kudos

You can't send an email when the invoice is created if you want to join several invoice.

in my example I call the VF31 with parameters.

in the drivers print program, I open on time the spool id, and I close it after the end of my set (customer)

Here my example :

REPORT zfi_vf31
       NO STANDARD PAGE HEADING.

*------------------------------ TABLES -------------------------------*

TABLES: nase ,
        vbrk .

*------------------------------- TYPES -------------------------------*

*------------------------------- DATA --------------------------------*

CONSTANTS: appl(2) VALUE 'V3',
           actvt(2) VALUE '04',        " activity for output processing
           true     VALUE 'X',
           false    VALUE ' '.

DATA : BEGIN OF it_vbrk OCCURS 0 ,
         vbeln TYPE vbeln_vf ,
       END   OF it_vbrk ,

       BEGIN OF it_nast OCCURS 0 ,
         objky TYPE na_objkey ,
       END   OF it_nast ,

       BEGIN OF it_nast2 OCCURS 0 ,
         objky TYPE na_objkey ,
       END   OF it_nast2 .


RANGES : r_vkorg FOR vbrk-vkorg ,
         r_vtweg FOR vbrk-vtweg ,
         r_spart FOR vbrk-spart ,
         r_land1 FOR vbrk-land1 .

*------------------------- SELECTION SCREEN --------------------------*
* A1. message

SELECTION-SCREEN BEGIN OF BLOCK message WITH FRAME TITLE text-001.
SELECT-OPTIONS:
  rg_kschl FOR nase-kschl MEMORY ID nac,
  rg_nacha FOR nase-nacha.
PARAMETERS:
  pm_nsort LIKE nase-sorv3 DEFAULT '01' OBLIGATORY,
  pm_vermo TYPE na_vermo_new DEFAULT '1' OBLIGATORY,
  pm_verdi LIKE nase-verdi NO-DISPLAY.
SELECTION-SCREEN END OF BLOCK message.

SELECTION-SCREEN SKIP.

* A2. billing

SELECTION-SCREEN BEGIN OF BLOCK application WITH FRAME TITLE text-002.
SELECT-OPTIONS:
  rg_vbeln FOR vbrk-vbeln MEMORY ID vf,
  rg_fkdat FOR vbrk-fkdat MEMORY ID dvo,
  rg_kkber FOR vbrk-kkber NO INTERVALS OBLIGATORY .
PARAMETERS:
  pm_allel LIKE vbco7-allel DEFAULT true,
  pm_allea LIKE vbco7-allea DEFAULT true,
  pm_alleb LIKE vbco7-alleb,
  pm_allei LIKE vbco7-allei,
  pm_allef LIKE vbco7-allef,
  pm_alled LIKE vbco7-allef.
PARAMETERS:
  pm_vkorg LIKE vbrk-vkorg MEMORY ID vko,
  pm_vtweg LIKE vbrk-vtweg MEMORY ID vtw,
  pm_spart LIKE vbrk-spart MEMORY ID spa.
SELECT-OPTIONS:
  rg_kunag FOR vbrk-kunag MATCHCODE OBJECT debi,
  rg_kunrg FOR vbrk-kunag MATCHCODE OBJECT debi.
PARAMETERS:
  pm_land1 LIKE vbrk-land1 MEMORY ID vll.
SELECTION-SCREEN END OF BLOCK application.

SELECTION-SCREEN SKIP.

SELECTION-SCREEN BEGIN OF BLOCK selection WITH FRAME TITLE text-003.
PARAMETERS:
  n_select TYPE na_sel_nast RADIOBUTTON GROUP slct,
  f_select TYPE na_sel_vbrk RADIOBUTTON GROUP slct.
SELECTION-SCREEN END OF BLOCK selection
.

*------------------------------ EVENTS -------------------------------*
* restricted F4-help to message (output) types of the application

INITIALIZATION.
  nase-kappl = appl.

* It's difficult to transfer billing numbers to objectkeys in order
* to get position messages too. Therfore only a single value or an
* intervall is allowed.

AT SELECTION-SCREEN ON rg_vbeln.
  LOOP AT rg_vbeln.
    IF ( rg_vbeln = 'E' ) OR
    ( ( rg_vbeln-option <> 'EQ' ) AND ( rg_vbeln-option <> 'BT' ) ).
      MESSAGE e076(vn).
    ENDIF.
  ENDLOOP.

*------------------------------- MAIN --------------------------------*

START-OF-SELECTION.

  IF NOT rg_kkber[] IS INITIAL.
    IF pm_vkorg NE space.
      MOVE : pm_vkorg TO r_vkorg-low ,
             'I'      TO r_vkorg-sign ,
             'EQ'     TO r_vkorg-option.
    ENDIF.
    IF pm_spart NE space.
      MOVE : pm_spart TO r_spart-low ,
             'I'      TO r_spart-sign ,
             'EQ'     TO r_spart-option.
    ENDIF.
    IF pm_vtweg NE space.
      MOVE : pm_vtweg TO r_vtweg-low ,
             'I'      TO r_vtweg-sign ,
             'EQ'     TO r_vtweg-option.
    ENDIF.
    IF pm_land1 NE space.
      MOVE : pm_land1 TO r_land1-low ,
             'I'      TO r_land1-sign ,
             'EQ'     TO r_land1-option.
    ENDIF.
    SELECT vbeln
           INTO TABLE it_vbrk
           FROM vbrk
           WHERE vbeln IN rg_vbeln
           AND   fkdat IN rg_fkdat
           AND   vkorg IN r_vkorg
           AND   vtweg IN r_vtweg
           AND   spart IN r_spart
           AND   kunag IN rg_kunag
           AND   kunrg IN rg_kunrg
           AND   land1 IN r_land1
           AND   kkber IN rg_kkber.
    IF sy-subrc NE space.
      WRITE /1 text-e02.
      STOP.
    ENDIF.
    LOOP AT it_vbrk.
      MOVE it_vbrk-vbeln TO it_nast-objky.
      APPEND it_nast.
    ENDLOOP.
    REFRESH it_vbrk.
    IF pm_vermo EQ '1'.
      SELECT objky
             INTO TABLE it_nast2
             FROM nast
             FOR ALL ENTRIES IN it_nast
             WHERE kappl EQ 'V3'
             AND   kschl IN rg_kschl
             AND   objky EQ it_nast-objky
             AND   vstat EQ '0'.
    ELSE.
      SELECT objky
             INTO TABLE it_nast2
             FROM nast
             FOR ALL ENTRIES IN it_nast
             WHERE kappl EQ 'V3'
             AND   kschl IN rg_kschl
             AND   objky EQ it_nast-objky
             AND   vstat NE '0'.
    ENDIF.

    LOOP AT it_nast2.
      MOVE it_nast2-objky+0(10) TO it_vbrk-vbeln.
      APPEND it_vbrk.
    ENDLOOP.
    IF sy-dbcnt GT 2800.
      WRITE : /1 text-e01.
      STOP.
    ELSEIF sy-dbcnt EQ 0.
      WRITE : /1 text-e02.
      STOP.
    ENDIF.
    REFRESH rg_vbeln.
    CLEAR   rg_vbeln.
    LOOP AT it_vbrk.
      MOVE : 'I'           TO rg_vbeln-sign ,
             'EQ'          TO rg_vbeln-option ,
             it_vbrk-vbeln TO rg_vbeln-low.
      APPEND rg_vbeln.
    ENDLOOP.
  ENDIF.

  SUBMIT sd70av3a WITH rg_kschl IN rg_kschl
                  WITH rg_nacha IN rg_nacha
                  WITH pm_nsort EQ pm_nsort
                  WITH pm_vermo EQ pm_vermo
                  WITH pm_verdi EQ pm_verdi
                  WITH rg_vbeln IN rg_vbeln
                  WITH rg_fkdat IN rg_fkdat
                  WITH pm_allel EQ pm_allel
                  WITH pm_allea EQ pm_allea
                  WITH pm_alleb EQ pm_alleb
                  WITH pm_allei EQ pm_allei
                  WITH pm_allef EQ pm_allef
                  WITH pm_alled EQ pm_alled
                  WITH pm_vkorg EQ pm_vkorg
                  WITH pm_vtweg EQ pm_vtweg
                  WITH pm_spart EQ pm_spart
                  WITH rg_kunag IN rg_kunag
                  WITH rg_kunrg IN rg_kunrg
                  WITH pm_land1 EQ pm_land1
                  WITH n_select EQ n_select
                  WITH f_select EQ f_select
                  AND RETURN.


END-OF-SELECTION.

0 Kudos

And here the drivers program :

FORM processing USING proc_screen
                CHANGING cf_retcode.

  DATA: ls_print_data_to_read TYPE lbbil_print_data_to_read.
  DATA: ls_bil_invoice TYPE lbbil_invoice.
  DATA: lf_fm_name            TYPE rs38l_fnam.
  DATA: ls_control_param      TYPE ssfctrlop.
  DATA: ls_composer_param     TYPE ssfcompop.
  DATA: ls_recipient          TYPE swotobjid.
  DATA: ls_sender             TYPE swotobjid.
  DATA: lf_formname           TYPE tdsfname.
  DATA: ls_addr_key           LIKE addr_key.
  DATA: ls_dlv-land           LIKE vbrk-land1.
  DATA: ls_job_info           TYPE ssfcrescl.
  DATA : is_kond  LIKE lbbil_hd_kond ,
         is_price LIKE lbbil_it_price ,
         is_kond2 LIKE lbbil_it_kond .
  DATA : w_rfbsk      TYPE rfbsk ,
         w_num_exemp  TYPE na_anzal.
  DATA : w_spool       TYPE char10 ,
         w_parnr       TYPE parnr  ,
         w_num_feuille TYPE i ,
         w_nb_feuille  TYPE i ,
         w_spoolid     TYPE rspoid ,
         w_modulo      TYPE i.

* SmartForm from customizing table TNAPR

  lf_formname = tnapr-sform.

* determine print data

  PERFORM set_print_data_to_read USING    lf_formname
                                 CHANGING ls_print_data_to_read
                                 cf_retcode.

  IF cf_retcode = 0.

* select print data

    PERFORM get_data USING    ls_print_data_to_read
                     CHANGING ls_addr_key
                              ls_dlv-land
                              ls_bil_invoice
                              cf_retcode.
  ENDIF.

* Cas des avoirs négatifs.

  IF ls_bil_invoice-hd_gen-bil_cat    NE 'P' AND
     ls_bil_invoice-hd_gen-bil_vbtype EQ 'O' AND
     ls_bil_invoice-hd_gen-bil_netwr  LT 0.
    ls_bil_invoice-hd_gen-bil_netwr = - ls_bil_invoice-hd_gen-bil_netwr.
    ls_bil_invoice-hd_gen-bil_disc  = - ls_bil_invoice-hd_gen-bil_disc.
    ls_bil_invoice-hd_gen-bil_tax   = - ls_bil_invoice-hd_gen-bil_tax.
    ls_bil_invoice-hd_gen-dpend     = - ls_bil_invoice-hd_gen-dpend.
    ls_bil_invoice-hd_gen-dpmws_end = - ls_bil_invoice-hd_gen-dpmws_end.
    ls_bil_invoice-hd_komk-supos    = - ls_bil_invoice-hd_komk-supos.
    ls_bil_invoice-hd_komk-fkwrt    = - ls_bil_invoice-hd_komk-fkwrt.
    LOOP AT ls_bil_invoice-hd_kond
         INTO is_kond.
      is_kond-kawrt = - is_kond-kawrt.
      is_kond-kwert = - is_kond-kwert.
      MODIFY ls_bil_invoice-hd_kond
             FROM is_kond.
    ENDLOOP.
    LOOP AT ls_bil_invoice-it_price
         INTO is_price.
      is_price-kzwi1 = - is_price-kzwi1.
      is_price-kzwi2 = - is_price-kzwi2.
      is_price-kzwi3 = - is_price-kzwi3.
      is_price-kzwi4 = - is_price-kzwi4.
      is_price-kzwi5 = - is_price-kzwi5.
      is_price-kzwi6 = - is_price-kzwi6.
      is_price-netwr = - is_price-netwr.
      is_price-mwsbp = - is_price-mwsbp.
      MODIFY ls_bil_invoice-it_price
             FROM is_price.
    ENDLOOP.
    LOOP AT ls_bil_invoice-it_kond
         INTO is_kond2.
      is_kond2-kwert = - is_kond2-kwert.
      MODIFY ls_bil_invoice-it_kond
             FROM is_kond2.
    ENDLOOP.
    MOVE 'M' TO ls_bil_invoice-hd_gen-bil_vbtype.
  ENDIF.

  IF cf_retcode = 0.
    PERFORM set_print_param USING    ls_addr_key
                                     ls_dlv-land
                            CHANGING ls_control_param
                                     ls_composer_param
                                     ls_recipient
                                     ls_sender
                                     cf_retcode.
  ENDIF.

  IF cf_retcode = 0.

* determine smartform function module for invoice

    CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
         EXPORTING  formname           = lf_formname

*                 variant            = ' '
*                 direct_call        = ' '

         IMPORTING  fm_name            = lf_fm_name
         EXCEPTIONS no_form            = 1
                    no_function_module = 2
                    OTHERS             = 3.
    IF sy-subrc <> 0.

*   error handling

      cf_retcode = sy-subrc.
      PERFORM protocol_update.
    ENDIF.
  ENDIF.

  IF cf_retcode = 0.

*   Contrôle passage en compta.

    SELECT SINGLE rfbsk
           INTO w_rfbsk
           FROM vbrk
           WHERE vbeln EQ ls_bil_invoice-hd_gen-bil_number.
    IF sy-subrc NE space.
      MESSAGE e019(zsd_001).
      STOP.
    ENDIF.
    IF w_rfbsk NE 'C' AND
       w_rfbsk NE 'D'.
      MESSAGE e020(zsd_001).
    ENDIF.

    IF ls_bil_invoice-hd_gen-bil_type NE 'ZF5' AND
       ls_bil_invoice-hd_gen-bil_type NE 'ZF8'.
      IF nast-kschl EQ 'ZFD2'.
        PERFORM p_check_repeat.
      ELSE.
        " Début ajout Nassim
        IF ls_bil_invoice-hd_gen-bil_edate > '20090713'. "REZO
          " fin ajout Nassim
          MOVE 'ZFD2' TO nast-kschl.
          PERFORM p_check_repeat.
          MOVE 'ZFD0' TO nast-kschl.
          IF repeat IS INITIAL.
            MESSAGE e018(zsd_001).
            STOP.
          ENDIF.
          " Début ajout Nassim
        ELSE.
          PERFORM p_check_repeat.
        ENDIF.
        " fin ajout Nassim
      ENDIF.
    ENDIF.

    IF ls_composer_param-tdcopies EQ 0.
      nast_anzal = 1.
    ELSE.
      nast_anzal = ls_composer_param-tdcopies.
    ENDIF.
    ls_composer_param-tdcopies = 1.
    DO nast_anzal TIMES.
      MOVE sy-index TO w_num_exemp.

* In case of repetition only one time archiving

      IF sy-index > 1 AND nast-tdarmod = 3.
        nast_tdarmod = nast-tdarmod.
        nast-tdarmod = 1.
        ls_composer_param-tdarmod = 1.
      ENDIF.
      IF sy-index NE 1 AND repeat IS INITIAL.
        repeat = 'X'.
      ENDIF.

*      IF ls_control_param-device EQ 'PRINTER'.

      IF nast-kschl EQ 'ZFD0'.
        CONCATENATE 'ProForma.'(001)
                    ls_bil_invoice-hd_gen-bil_number
                    INTO ls_composer_param-tdcovtitle
                    SEPARATED BY ' '.

      ELSE.
        MOVE : ' ' TO ls_composer_param-tdnewid ,
               ' ' TO ls_composer_param-tdfinal ,
               ' ' TO ls_composer_param-tdimmed ,
               sy-uname TO ls_composer_param-tdreceiver .

        SPLIT nast-tdcovtitle AT ';' INTO w_spool w_parnr.


      ENDIF.

* call smartform invoice

      CALL FUNCTION lf_fm_name
           EXPORTING
                      archive_index        = toa_dara
                      archive_parameters   = arc_params
                      control_parameters   = ls_control_param

*                 mail_appl_obj        =

                      mail_recipient       = ls_recipient
                      mail_sender          = ls_sender
                      output_options       = ls_composer_param
                      user_settings        = space
                      is_bil_invoice       = ls_bil_invoice
                      is_nast              = nast
                      is_repeat            = repeat
                      w_num_exemp          = w_num_exemp
                      it_tax_text           = itg_text_tax
           IMPORTING  job_output_info      = ls_job_info

*                     document_output_info =
*                     job_output_options   =

           EXCEPTIONS formatting_error     = 1
                      internal_error       = 2
                      send_error           = 3
                      user_canceled        = 4
                      OTHERS               = 5.
      IF sy-subrc <> 0.

*   error handling

        cf_retcode = sy-subrc.
        PERFORM protocol_update.

* get SmartForm protocoll and store it in the NAST protocoll

        PERFORM add_smfrm_prot.
      ENDIF.
    ENDDO.

* get SmartForm spoolid and store it in the NAST protocoll

    DATA ls_spoolid LIKE LINE OF ls_job_info-spoolids.
    LOOP AT ls_job_info-spoolids INTO ls_spoolid.
      IF ls_spoolid NE space.
        PERFORM protocol_update_spool USING '342' ls_spoolid
                                            space space space.

*       Export du numéro de spool.

        IMPORT num_feuille = w_num_feuille
               nb_feuille  = w_nb_feuille
               modulo      = w_modulo
               spool_id    = w_spoolid
               FROM MEMORY ID w_spool.
        EXPORT num_feuille = w_num_feuille
               nb_feuille  = w_nb_feuille
               modulo      = w_modulo
               spool_id    = ls_spoolid
               TO MEMORY ID w_spool.
      ENDIF.
    ENDLOOP.
    ls_composer_param-tdcopies = nast_anzal.
    IF NOT nast_tdarmod IS INITIAL.
      nast-tdarmod = nast_tdarmod.
      CLEAR nast_tdarmod.
    ENDIF.


  ENDIF.

* get SmartForm protocoll and store it in the NAST protocoll
* PERFORM ADD_SMFRM_PROT.

ENDFORM. "PROCESSING

0 Kudos

Hi Sowmya

In your case you will have to design it using various option suggested above

Nabheet

0 Kudos

Thanks for the sample code Fred.

I'm using SAPscript. In the driver Program, I've written the code for processing email as shown in my thread (topmost).

Where can we control multiple attachments?

The custom code of VF31 you've shown submits SD70AV3A.

Thanks & Regards,
Sowmya

0 Kudos

I'm sorry, I didn't like SAPSCript, and I don't know how to convert it in PDF.

but, when you do this job you just have to add several document to the mail content.

the program SD70xxx is the default print program --> VF31

regards

Fred

0 Kudos

I've already converted it to PDF.. Code is shown in my above thread.

Which Table do we need to use for LOOPing i.e., attaching multiple docs?

Thanks & Regards,
Sowmya

0 Kudos

* Attach PDF Invoice in the mail

  DATA: lv_adrnr   TYPE kna1-adrnr,

        lv_name1   TYPE kna1-name1,

        l_sub      TYPE so_obj_des,

        l_invoice  TYPE vbeln_vf,

        p_receiver TYPE so_recname.

  DATA:

   lo_send_request TYPE REF TO cl_bcs ,

   lo_document     TYPE REF TO cl_document_bcs,

   lo_sender       TYPE REF TO if_sender_bcs  ,

   lo_recipient    TYPE REF TO if_recipient_bcs ,

   lt_message_body TYPE bcsy_text ,

   lx_document_bcs TYPE REF TO cx_document_bcs ,

   lv_send         TYPE ad_smtpadr,

   lv_sent_to_all  TYPE os_boolean,

   w_subject(50)   TYPE c.

*  <----- This must be called several times


*The OTF contents are  converted to PDF Format (XSTRING)

  CALL FUNCTION 'CONVERT_OTF'

    EXPORTING

      format                = c_pdf

      max_linewidth         = 132

    IMPORTING

      bin_filesize          = w_bin_size

      bin_file              = w_pdf_xstring

    TABLES

      otf                   = t_datab[]

      lines                 = t_line[]

    EXCEPTIONS

      err_max_linewidth     = 1

      err_format            = 2

      err_conv_not_possible = 3

      err_bad_otf           = 4

      OTHERS                = 5.

  IF sy-subrc <> 0.

    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno

            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

  ENDIF.

* XSTRING format is then converted to Binary Format (SOLIX_TAB) to use in the attachment mail

  CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'

    EXPORTING

      buffer     = w_pdf_xstring

    TABLES

      binary_tab = g_objcont.

* <---  This is the beginning of the creation of your mail.

  CLASS cl_bcs DEFINITION LOAD.

  SELECT SINGLE adrnr INTO lv_adrnr

     FROM kna1

    WHERE kunnr = nast-parnr.

  IF sy-subrc EQ 0.

    SELECT SINGLE smtp_addr INTO lv_send

      FROM adr6

      WHERE addrnumber = lv_adrnr.

    IF sy-subrc NE 0.

      MESSAGE e999(z1) WITH 'Email id is not updated for customer: ' nast-objky.

    ENDIF.

  ENDIF.

*  "create send request

  lo_send_request = cl_bcs=>create_persistent( ).

* Fetch Name of the Customer

  SELECT SINGLE name1 INTO lv_name1

     FROM kna1

    WHERE kunnr = nast-parnr.

  CONCATENATE lv_name1 ',' INTO lv_name1.

  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'

    EXPORTING

      input  = nast-objky

    IMPORTING

      output = l_invoice.

* Create message body and name of the attachment

  APPEND lv_name1 TO lt_message_body.

  APPEND INITIAL LINE TO lt_message_body.

  APPEND 'Please find the attached Invoice.' TO lt_message_body.

  APPEND l_invoice TO lt_message_body.

  APPEND INITIAL LINE TO lt_message_body.

  APPEND 'This is a system generated email. Please DO NOT REPLY to this email.' TO lt_message_body.

  APPEND INITIAL LINE TO lt_message_body.

  APPEND 'Thank You!' TO lt_message_body.

  CONCATENATE 'Invoice ' nast-objky INTO w_subject.

  CONCATENATE 'Customer Invoice :' l_invoice INTO l_sub.

* Email Body

  lo_document = cl_document_bcs=>create_document(

                                i_type = 'RAW'

                                i_text = lt_message_body

                                i_subject = l_sub ).

* <-- here is the loop on your invoice

*  <--  you must insert here your OTF --> PDF conversion.


* Add attachment

  TRY.

      CALL METHOD lo_document->add_attachment

        EXPORTING

          i_attachment_type    = 'PDF'

          i_attachment_subject = w_subject

          i_att_content_hex    = g_objcont.

    CATCH cx_document_bcs INTO lx_document_bcs.

  ENDTRY.

* <-- end of the loop on invoices


* Pass the document to send request

  CALL METHOD lo_send_request->set_document( lo_document ).

*  Create sender / Set sender

  lo_sender = cl_sapuser_bcs=>create( sy-uname ).

* Add sender to send request

  CALL METHOD lo_send_request->set_sender

    EXPORTING

      i_sender = lo_sender.

* Create recipient

  lo_recipient = cl_cam_address_bcs=>create_internet_address( lv_send ).

*Set recipient

  CALL METHOD lo_send_request->add_recipient

    EXPORTING

      i_recipient = lo_recipient

      i_express   = 'X'.

* Set send immediately

  lo_send_request->set_send_immediately( 'X' ).

* Send email

  lo_send_request->send(

   EXPORTING

   i_with_error_screen = 'X'

   RECEIVING

   result = lv_sent_to_all ).

  IF sy-subrc EQ space.

    MESSAGE 'Mail sent successfully.' TYPE 'S'.

  ELSE.

    MESSAGE 'Error sending Email' TYPE 'E'.

    ROLLBACK WORK.

  ENDIF.

0 Kudos

Thanks Fred.

LOOPing using which Table was my doubt.

-Sowmya

0 Kudos

You loop on the call of the SAPScript

that's all

so maybe you store your invoice number in a table like xvbrk (type table of vbrk)

LOOP AT XVBRK.

--> Call SAPScript

--> Get OTF

--> Convert OTF

--> lo_document->add_attachment

ENDLOOP.

0 Kudos

how to do it..can you tell me the step

Former Member
0 Kudos

Hi sowmya ,
Were you able to solve the issue ?

Regards ,
Giri

0 Kudos

No Giri.

I got to know the alternate solution : to use 'Invoice List' (combine all the Invoices into one ) using the tcode VF21, then send it as a single attachment.

-Sowmya

0 Kudos

This message was moderated.

Former Member
0 Kudos

Hi Sowmya,

Can you share your development. Even I am not able to send single auto mail after Invoice created through VF01.

Thanks in advance . . .