Cerca nel blog

giovedì 12 settembre 2019

ABAP: Invio Mail con allegato PDF con la classe CL_BCS

Invio Mail con allegato PDF con classe CL_BCS

Di seguito riporto un semplice programma ABAP, che legge i dati di un OdA, passato come parametro di input, richiama uno smartforms custom (voi richiamate il vostro smartforms) ed invia la mail con un PDF allegato:


REPORT zprova_invio_mail.

SELECTION-SCREEN BEGIN OF BLOCK 1 WITH FRAME TITLE text-001.
PARAMETERS: p_ebeln   TYPE ebeln  OBLIGATORY.
SELECTION-SCREEN END OF BLOCK 1.

********************
** DICHIARAZIONI

TYPES: BEGIN OF ty_oda,
         ebeln      TYPE ebeln,
         ebelp      TYPE ebelp,
         matnr      TYPE matnr,
         menge      TYPE bstmg,
         banfn      TYPE banfn,
         bnfpo      TYPE bnfpo,
         werks      TYPE ewerk,
         matkl      TYPE matkl,
         meins      TYPE bstme,
         konnr      TYPE konnr,
         ktpnr      TYPE ktpnr,
         fistl      TYPE fistl,
         netpr      TYPE bprei,
         peinh      TYPE epein,
         bprme      TYPE bbprm,
         prezzo_tot TYPE bwert,
       END OF ty_oda,
       tt_oda TYPE STANDARD TABLE OF ty_oda.

DATA: send_request     TYPE REF TO cl_bcs,
      bcs_exception    TYPE REF TO cx_bcs,
      gv_sender        TYPE REF TO if_sender_bcs,
      gv_recipient     TYPE REF TO if_recipient_bcs,
      gt_text          TYPE bcsy_text,
      gv_subject_short TYPE so_obj_des,
      gv_subject_long  TYPE string,
      document         TYPE REF TO cl_document_bcs,
      gt_ordini        TYPE tt_oda,
      gt_dati_stampa   TYPE STANDARD TABLE OF zmm_st_ce_notifica_rd,
      i_dt_crea_oda    TYPE sy-datum,
      gv_contratto     TYPE eban-konnr,
      gv_id_cat(10)    TYPE c,
      gv_desc_cat(60)  TYPE c,
      o_tb_otf_pdf     TYPE STANDARD TABLE OF itcoo,
      pdf_size         TYPE so_obj_len,
      pdf_xstring      TYPE xstring,
      pdf_content      TYPE solix_tab.

START-OF-SELECTION.

* Setto variabili che mi servono per il pdf.
  gv_contratto = '54949494'.
  i_dt_crea_oda = sy-datum.
  gv_id_cat = 'CAT01'.
  gv_desc_cat = 'DESC CAT'.
  PERFORM get_data.

  PERFORM genera_pdf.

  PERFORM invio_mail.

END-OF-SELECTION.


*&---------------------------------------------------------------------*
*&      Form  GET_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM get_data .
  FREE: gt_ordini, gt_dati_stampa, o_tb_otf_pdf.

  SELECT  a~ebeln, b~ebelp, b~matnr, b~menge,
          b~banfn, b~bnfpo, b~werks, b~matkl,
          b~meins, b~konnr, b~ktpnr,
          b~fistl, b~netpr, b~peinh,
          b~bprme, b~netwr
    INTO TABLE @gt_ordini
        FROM ( ekko AS a
              INNER JOIN ekpo AS b ON a~ebeln = b~ebeln
             )
       WHERE a~ebeln = @p_ebeln
         AND a~bstyp = 'F'. "SOlo ordini di acquisto


* Valorizzo dati per la tsmpa in pdf (smartforms)
  gt_dati_stampa = VALUE #( FOR ls_ordini IN gt_ordini
                              ( banfn    = ls_ordini-banfn
                                bnfpo    = ls_ordini-bnfpo
                                txz01    = 'TESTO'
                                matnr    = ls_ordini-matnr
                                werks    = ls_ordini-werks
                                matkl    = ls_ordini-matkl
                                menge    = ls_ordini-menge
                                meins    = ls_ordini-meins
                                konnr    = ls_ordini-konnr
                                ktpnr    = ls_ordini-ktpnr
                                fistl    = ls_ordini-fistl
                                netpr    = ls_ordini-netpr
                                peinh    = ls_ordini-peinh
                                bprme    = ls_ordini-bprme
                                prezzo_tot = ls_ordini-prezzo_tot
                                ebelp    = ls_ordini-ebelp
                                 ) ).

  IF sy-subrc NE 0.
    MESSAGE e000(00) WITH 'Ordine di acquisto inserito inesistente'.
  ENDIF.

ENDFORM.


*&---------------------------------------------------------------------*
*&      Form  INVIO_MAIL
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM invio_mail .

  DATA: lv_app_mail             TYPE adr6-smtp_addr,
        lv_righe_corpo_mail     TYPE soli,
        lv_num                  TYPE so_obj_len,
        lv_sent_to_all          TYPE os_boolean,
        lv_mode(3)              VALUE 'INT',
        lt_recs_with_error      TYPE bcsy_re,               "#EC NEEDED
        lt_orig_recs_with_error TYPE bcsy_ercp,
        lv_menge                TYPE string.





DATA : wda_name     TYPE string,
       in_protocol  
TYPE string,
       out_host     
TYPE string,
       out_port     
TYPE string,
       out_protocol 
TYPE string,
       val          
TYPE string,
       g_url        
TYPE string.


  FREE: send_request, bcs_exception.

*Chiamata BCS
  TRY.

**  Creazione canale di trasmissione
      send_request = cl_bcs=>create_persistent( ).

**  Settiamo il mittente
      CLEAR: gv_sender.
      gv_sender = cl_sapuser_bcs=>create( sy-uname ).

      CALL METHOD send_request->set_sender
        EXPORTING
          i_sender = gv_sender.

* SE VOGLIAMO SPECIFICARE UN UTENTE DIVERSO DA QUELLO CHE ESEGUE IL PROGRAMMA
*        clear: lv_app_mail.
*        lv_app_mail = 'marco.rossi@societa.com'.
*        clear: gv_sender.
*        gv_sender = cl_cam_address_bcs=>create_internet_address( i_address_string = lv_app_mail
*                                                                 i_address_name   = 'Marco Rossi').
*
*        CALL METHOD send_request->set_sender
*          EXPORTING
*            i_sender = gv_sender.
** ------------

**  Settiamo il destinatario o destinatari
** Primo Destinatario
      CLEAR: lv_app_mail, gv_recipient.
      lv_app_mail = 'mauro.neri@
societa.com'.
      gv_recipient = cl_cam_address_bcs=>create_internet_address( i_address_string = lv_app_mail
                                                                  i_address_name   = 'Mauro Neri').

      CALL METHOD send_request->add_recipient
        EXPORTING
          i_recipient = gv_recipient
          i_express   = 'X'.

** Secondo Destinatario
      CLEAR: lv_app_mail, gv_recipient.
      lv_app_mail = 'franco.califano@
societa.com'.
      gv_recipient = cl_cam_address_bcs=>create_internet_address( i_address_string = lv_app_mail
                                                                  i_address_name   = 'Franco Califano').

      CALL METHOD send_request->add_recipient
        EXPORTING
          i_recipient = gv_recipient
          i_copy      = 'X'.
** ------------

** Corpo della mail
      FREE: gt_text.
      CLEAR: lv_righe_corpo_mail.
      CONCATENATE 'Salve,'
                  '<BR>'
             INTO lv_righe_corpo_mail-line.
      APPEND lv_righe_corpo_mail TO gt_text.

      CLEAR: lv_righe_corpo_mail.
      CONCATENATE 'Questo è l''elenco dei materiali presenti nell''ordine di acquisto: '
                  '<BR>'
                  '<BR>'
             INTO lv_righe_corpo_mail-line.
      APPEND lv_righe_corpo_mail TO gt_text.

** Costruzione tabella HTML con i dati dell'oda selezionata
      CLEAR lv_righe_corpo_mail.
      lv_righe_corpo_mail-line = '<html> <body style="background-color:#FFFFFF;"> <basefont face="arial, verdana, courier" size="2" >'.
      APPEND lv_righe_corpo_mail TO gt_text.

      CLEAR lv_righe_corpo_mail.
      lv_righe_corpo_mail-line = '<table style="MARGIN: 10px" bordercolor="#050211" width = "100%" border="1px"> '. 
APPEND lv_righe_corpo_mail TO gt_text.

      CLEAR lv_righe_corpo_mail.
      lv_righe_corpo_mail = '<tr><th>Nr. Doc. Acquisto</th><th>Pos. Doc. Acquisto</th><th>Nr. Materiale</th><th>Quantità</th></tr>'.
      APPEND lv_righe_corpo_mail TO gt_text.

      LOOP AT gt_ordini ASSIGNING FIELD-SYMBOL(<lfs_ordini>).
        CLEAR: lv_righe_corpo_mail, lv_menge.
        lv_menge = <lfs_ordini>-menge.
        CONCATENATE '<tr><td align="center">' <lfs_ordini>-ebeln '</td><td align="center">' <lfs_ordini>-ebelp '</td><td align="center">'
                        <lfs_ordini>-matnr '</td><td align="center">' lv_menge '</td></tr>' INTO lv_righe_corpo_mail.
        APPEND lv_righe_corpo_mail TO gt_text.
      ENDLOOP.

      CLEAR lv_righe_corpo_mail.
      lv_righe_corpo_mail-line = '</table></body></html>'.
      APPEND lv_righe_corpo_mail TO gt_text.



*Aggiungo nel corpo della mail , anche un lilnk ad una transazione SAP

*********************************************************
* -Generating URL for SAP Trasaction ( SAP GUI for HTML )
*********************************************************
      
CALL METHOD cl_http_server=>if_http_server~get_location
        
EXPORTING
          protocol     
= in_protocol
          server       
= cl_wdr_task=>server
        
IMPORTING
          host         
= out_host
          port         
= out_port
          out_protocol 
= out_protocol.

      val 
= sy-mandt.


CONCATENATE out_protocol '://' out_host ':' out_port '/sap/bc/gui/sap/its/webgui? ~transaction=Nome_transazione' INTO g_url.



      CALL METHOD cl_http_server=>append_field_url
        
EXPORTING
          name  
= 'sap-client'
          
value = val
        
CHANGING
          url   
= g_url.

 

      CONCATENATE '<a href="' g_url '"  > Click Link  </a>' ' ' INTO lv_righe_corpo_mail-line.
      APPEND lv_righe_corpo_mail TO gt_text.

** ------------------------

** Oggetto della mail SHORT (che si vede nella sost)
      CLEAR: gv_subject_short.
      gv_subject_short = 'Oggetto della mail di prova da inviare'.

** Modifica dell'oggetto della mail, visibile solo nella mail e non nella SOST
      CLEAR: gv_subject_long.
      gv_subject_long = 'Oggetto LONG della mail di prova da inviare con più di 50 caratteri'.

*     Aggioro il contenuto PDf da allegare alla mail
      CLEAR: pdf_content.
      pdf_content = cl_document_bcs=>xstring_to_solix( pdf_xstring ).

      FREE: document.
** Creazione Mail con allegato corpo della mail e oggetto
      document = cl_document_bcs=>create_document(
                      i_type    = 'HTM'
                      i_text    = gt_text
                      i_subject = gv_subject_short
                      ).
      TRY.
          CALL METHOD send_request->set_message_subject
            EXPORTING
              ip_subject = gv_subject_long.
        CATCH cx_send_req_bcs .
      ENDTRY.

      document->add_attachment(
        EXPORTING
          i_attachment_type = 'PDF'
          i_attachment_subject = 'Form'
          i_attachment_size = pdf_size
          i_att_content_hex = pdf_content ).

** Aggiunta Documento alla mail
      CALL METHOD send_request->set_document( document ).

**  Invio MAIL
      CLEAR: lv_sent_to_all.
      CALL METHOD send_request->send(
        EXPORTING
          i_with_error_screen = 'X'
        RECEIVING
          result              = lv_sent_to_all ).

      COMMIT WORK AND WAIT.

**  Cattura Eccezione.
    CATCH cx_bcs INTO bcs_exception.
      RAISE error_send_mail.
  ENDTRY.

  MESSAGE s000(00) WITH 'Email inviata correttamente'.
ENDFORM.


*&---------------------------------------------------------------------*
*&      Form  GENERA_PDF
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM genera_pdf .
  DATA: lv_formname             TYPE tdsfname,
        lv_form_name_out        TYPE rs38l_fnam,
        lv_invio_mail(1)        TYPE c,
        ls_control_param        TYPE ssfctrlop,
        ls_output_options       TYPE ssfcompop,
        lv_user_settings        TYPE tdbool,
        st_document_output_info TYPE ssfcrespd,
        st_job_output_info      TYPE ssfcrescl,
        st_job_output_options   TYPE ssfcresop,
        lt_lines                TYPE STANDARD TABLE OF tline.

  CLEAR: lv_formname, lv_form_name_out, ls_control_param,
         ls_output_options, lv_user_settings,
         st_document_output_info,
         st_job_output_info, st_job_output_options,
         pdf_size.

* nome dello smartforms da richiamare per creare il PDF
  lv_formname = 'ZMM_SF_NOTIF_ODA'.
  lv_invio_mail = abap_true.

*Richiamo lo smartforms
  CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
    EXPORTING
      formname           = lv_formname
    IMPORTING
      fm_name            = lv_form_name_out
    EXCEPTIONS
      no_form            = 1
      no_function_module = 2
      OTHERS             = 3.


  IF lv_invio_mail = abap_false.
* In questo modo genero a video il pdf
    CLEAR: ls_control_param.
    ls_control_param-device  =  'PRINTER'.
    ls_control_param-no_dialog = abap_true.
    ls_control_param-preview = abap_true.
    ls_control_param-langu = 'I'.

    CLEAR: ls_output_options.
    ls_output_options-tdarmod = 1.
    ls_output_options-tddest = 'LOCL'.
    ls_output_options-tdimmed = abap_true.
    ls_output_options-tdreceiver = sy-uname.
    ls_output_options-tdcopies = '001'.

    lv_user_settings = abap_true.
  ELSE.
* In questo modo, creo il pdf ma non lo mostro.
    CLEAR: ls_control_param.
    ls_control_param-getotf    = abap_true.
    ls_control_param-no_dialog = abap_true.

    CLEAR: ls_output_options.
    ls_output_options-tdnoprev  = abap_true.
    ls_output_options-tddest = 'LOCL'.
    ls_output_options-tdnoprint = abap_true. "New

* Questa variabile permette di non considerare i settaggi
* dell'utente. E' utile quando all'utente non è settato la stampante di default
    lv_user_settings = ' '.
  ENDIF.

  CALL FUNCTION lv_form_name_out
    EXPORTING
      control_parameters   = ls_control_param
      output_options       = ls_output_options
      user_settings        = lv_user_settings
      it_oda               = gt_dati_stampa
      i_oda                = p_ebeln
      i_contratto          = gv_contratto
      i_id_catalogo        = gv_id_cat
      i_desc_catalogo      = gv_desc_cat
      i_dt_creazione       = i_dt_crea_oda
    IMPORTING
      document_output_info = st_document_output_info
      job_output_info      = st_job_output_info
      job_output_options   = st_job_output_options
    EXCEPTIONS
      formatting_error     = 1
      internal_error       = 2
      send_error           = 3
      user_canceled        = 4
      OTHERS               = 5.

  IF sy-subrc NE 0 OR st_job_output_info-otfdata[] IS INITIAL.
    MESSAGE e000(00) WITH 'PDF non generato'.
  ENDIF.

*Converto i dati di output dello smartforms in formato OTF (XSTRING)
  CLEAR: pdf_xstring.
  FREE: lt_lines.

  CALL FUNCTION 'CONVERT_OTF'
    EXPORTING
      format                = 'PDF'
    IMPORTING
      bin_filesize          = pdf_size
      bin_file              = pdf_xstring
    TABLES
      otf                   = st_job_output_info-otfdata
      lines                 = lt_lines
    EXCEPTIONS
      err_max_linewidth     = 1
      err_format            = 2
      err_conv_not_possible = 3
      err_bad_otf           = 4
      OTHERS                = 5.
ENDFORM. 

1 commento:

  1. Grazie è stato molto utile. A me serviva inviare un PDF tramite webservice

    RispondiElimina