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 WITH FRAME TITLE text-001.
PARAMETERSp_ebeln   TYPE ebeln  OBLIGATORY.
SELECTION-SCREEN END OF BLOCK 1.

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

TYPESBEGIN 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.

DATAsend_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 .
  FREEgt_ordinigt_dati_stampao_tb_otf_pdf.

  SELECT  a~ebelnb~ebelpb~matnrb~menge,
          b~banfnb~bnfpob~werksb~matkl,
          b~meinsb~konnrb~ktpnr,
          b~fistlb~netprb~peinh,
          b~bprmeb~netwr
    INTO TABLE @gt_ordini
        FROM ekko AS a
              INNER JOIN ekpo AS 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(00WITH 'Ordine di acquisto inserito inesistente'.
  ENDIF.

ENDFORM.


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

  DATAlv_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.


  FREEsend_requestbcs_exception.

*Chiamata BCS
  TRY.

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

**  Settiamo il mittente
      CLEARgv_sender.
      gv_sender cl_sapuser_bcs=>createsy-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
      CLEARlv_app_mailgv_recipient.
      lv_app_mail 'mauro.neri@
societa.com'.
      gv_recipient cl_cam_address_bcs=>create_internet_addressi_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
      CLEARlv_app_mailgv_recipient.
      lv_app_mail 'franco.califano@
societa.com'.
      gv_recipient cl_cam_address_bcs=>create_internet_addressi_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
      FREEgt_text.
      CLEARlv_righe_corpo_mail.
      CONCATENATE 'Salve,'
                  '<BR>'
             INTO lv_righe_corpo_mail-line.
      APPEND lv_righe_corpo_mail TO gt_text.

      CLEARlv_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>).
        CLEARlv_righe_corpo_maillv_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)
      CLEARgv_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
      CLEARgv_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
      CLEARpdf_content.
      pdf_content cl_document_bcs=>xstring_to_solixpdf_xstring ).

      FREEdocument.
** 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_documentdocument ).

**  Invio MAIL
      CLEARlv_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(00WITH 'Email inviata correttamente'.
ENDFORM.


*&---------------------------------------------------------------------*
*&      Form  GENERA_PDF
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM genera_pdf .
  DATAlv_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.

  CLEARlv_formnamelv_form_name_outls_control_param,
         ls_output_optionslv_user_settings,
         st_document_output_info,
         st_job_output_infost_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
    CLEARls_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'.

    CLEARls_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.
    CLEARls_control_param.
    ls_control_param-getotf    abap_true.
    ls_control_param-no_dialog abap_true.

    CLEARls_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 OR st_job_output_info-otfdata[] IS INITIAL.
    MESSAGE e000(00WITH 'PDF non generato'.
  ENDIF.

*Converto i dati di output dello smartforms in formato OTF (XSTRING)
  CLEARpdf_xstring.
  FREElt_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.