Homelab, Linux, JS & ABAP (~˘▾˘)~
 

[ABAP] Send mail using CL_BCS

Find related example reports in package SBCOMS.

 TRY.

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

        DATA(lo_recipient) = cl_cam_address_bcs=>create_internet_address( i_address_string = lv_mailaddress ).

        DATA(lv_html_text) = |<BODY> | &&
                             |<p>Guten Tag,<br>| &&
                             |<br>| &&
                             |Es ist ein Fehler aufgetreten.<br>| &&
                             |Bitte schauen Sie in das Application Log.<br>| &&
                             |<br>| &&
                             |Vielen Dank!</p>| &&
                             |</BODY>|.

        DATA(lo_document) = cl_document_bcs=>create_document( i_type    = 'HTM'
                                                              i_text    = cl_document_bcs=>string_to_soli( ip_string = lv_html_text )
                                                              i_subject = |Fehler| ).

        " Erzeuge Business Communication Service und setze Objekte
        DATA(lo_send_request) = cl_bcs=>create_persistent( ).
        lo_send_request->set_sender( lo_sender ).           " Sender
        lo_send_request->add_recipient( lo_recipient ).     " Empfänger
        lo_send_request->set_document( lo_document ).       " Mailtext
        lo_send_request->set_send_immediately( abap_true ). " Mail sofort senden
        lo_send_request->send( ).                           " Sende Mail!
        COMMIT WORK.                                        " Ohne Commit wird keine Mail in der SOST auftauchen

        " Schreibe Fehler in das Log
      CATCH cx_address_bcs  INTO DATA(lx_address_bsc).
        mr_log->add_exception( i_exception = lx_address_bsc ).
      CATCH cx_send_req_bcs INTO DATA(lx_send_req_bcs).
        mr_log->add_exception( i_exception = lx_send_req_bcs ).
      CATCH cx_document_bcs INTO DATA(lx_document_bcs).
        mr_log->add_exception( i_exception = lx_document_bcs ).

  ENDTRY.

[ABAP] Log using CL_BAL_LOGOBJ

 DATA(lr_log) = NEW cl_bal_logobj( i_log_object        = 'ZMM'
                                   i_default_subobject = 'ZMM_LOGGING' ).

 lr_log->add_statustext( i_statustext = |Write a text.| ).

 lr_log->add_exception( lo_excp ).

 lr_log->add_errortext( lo_excp->get_longtext( ) ).

 lr_log->add_msg( i_probclass = '1' ).   "will use sy-msgty sy-msgid sy-msgno sy-msgv1 ...

 lr_log->save( i_client = sy-mandt ).

 lr_log->display( ).

Note: When using on EHP 7.40 you will get some confusing & & around your message texts.
https://tricktresor.de/blog/ausnahmen-mit-t100-nachricht-abap750/

Possible values for i_probclass:

[ABAP] SALV

    TRY.
        cl_salv_table=>factory( IMPORTING r_salv_table = DATA(alv_table)
                                CHANGING  t_table      = lt_display_data ).
        alv_table->display( ).

      CATCH cx_salv_msg.
    ENDTRY.

[ABAP] Modify Infotype

METHOD operate_it.

    DATA ls_return TYPE bapireturn1.
    DATA key       TYPE bapipakey.

    CALL FUNCTION 'BAPI_EMPLOYEE_ENQUEUE'
      EXPORTING
        number = is_2002-pernr
      IMPORTING
        return = ls_return.
    IF ls_return IS NOT INITIAL.
      RAISE EXCEPTION TYPE zcx_xxx MESSAGE ID ls_return-id TYPE ls_return-type NUMBER ls_return-number.
    ENDIF.

    CALL FUNCTION 'HR_INFOTYPE_OPERATION'
      EXPORTING
        infty         = '2002'
        number        = is_2002-pernr
        subtype       = is_2002-subty
        objectid      = is_2002-objps
        lockindicator = is_2002-sprps
        validityend   = is_2002-endda
        validitybegin = is_2002-begda
        recordnumber  = is_2002-seqnr
        record        = is_2002_chg
        operation     = iv_actio          "MOD,INS,DEL
        tclas         = 'A'
        dialog_mode   = '0'
      IMPORTING
        return        = ls_return
        key           = key.
    IF ls_return IS NOT INITIAL.
      RAISE EXCEPTION TYPE zcx_xxx MESSAGE ID ls_return-id TYPE ls_return-type NUMBER ls_return-number.
    ENDIF.

    CALL FUNCTION 'BAPI_EMPLOYEE_DEQUEUE'
      EXPORTING
        number = is_2002-pernr.

ENDMETHOD.

[ABAP] BAPI_ACC_DOCUMENT_POST

How to handle BAPI_ACC_DOCUMENT_POST with a document split at position 980. The method create_document fills the necessary tables and calls post_document, if it reaches position 980, to post the current document. Then the method create_document calls itself recursiv for the next positions.

  METHOD create_document.

    DATA: lt_pos                    TYPE TABLE OF bapiacgl09,
          lt_pos_amt                TYPE TABLE OF bapiaccr09.

    gr_listlog->append_log_entry( iv_type = gr_listlog->gc_log_type_info
                                  iv_text = |Beginne Belegerstellung|
                                  iv_alog = abap_true ).

    "Belegkopf
    DATA(ls_documentheader) = VALUE bapiache09( comp_code   = gs_sel-p_bukrs
                                                header_txt  = |header text|
                                                pstng_date  = sy-datum
                                                doc_date    = sy-datum
                                                fisc_year   = sy-datum(4)
                                                fis_period  = sy-datum+4(2)
                                                doc_type    = gs_sel-p_blart
                                                username    = sy-uname ).
    "Fülle Positionen
    LOOP AT it_xxx ASSIGNING FIELD-SYMBOL(<ls_xxx>).

      APPEND VALUE #( itemno_acc     = lines( lt_pos ) + 1
                      gl_account     = <ls_xxx>-hkont
                      stat_con       = abap_false
                      acct_type      = 'S'                      "Sachkonto
                      bus_area       = '0030'
                      fis_period     = sy-datum+4(2)
                      fisc_year      = sy-datum(4)
                      pstng_date     = sy-datum
                      value_date     = sy-datum
                      item_text      = |item text|
                      alloc_nmbr     = <ls_xxx>-zuonr
                      doc_type       = <ls_xxx>-blart
                      comp_code      = <ls_xxx>-bukrs
                      func_area      = '0030'
                      costcenter     = <ls_xxx>-kostl
                      tax_code       = <ls_xxx>-mwskz ) TO lt_pos.

      APPEND VALUE #( itemno_acc   = lines( lt_pos_amt ) + 1
                      curr_type    = '00'                       "Belegwährung
                      currency     = |EUR|
                      amt_doccur   = <ls_xxx>-betrg ) TO lt_pos_amt.

      "Belegsplit notwendig?
      IF lines( lt_pos ) = 980.
        gr_listlog->append_log_entry( iv_type = gr_listlog->gc_log_type_statistic
                                      iv_text = |Belegsplit notwendig!|
                                      iv_alog = abap_true ).

        "Verbuche die aktuellen Positionen
        post_document( is_documentheader = ls_documentheader
                       it_pos            = lt_pos
                       it_pos_amt        = lt_pos_amt ).

        "Rekursiver Aufruf der Methode! Nur mit den Sätzen die noch nicht verarbeitet wurden
        create_document( it_xxx = FILTER #( it_xxx USING KEY sort_key WHERE xxx = xxx ) ).

        "Verlasse bei Rekursion hier
        RETURN.
      ENDIF.



    ENDLOOP.


    "Wenn alle Positionen hinzugefügt, lege den Beleg an
    post_document( is_documentheader = ls_documentheader
                   it_pos            = lt_pos
                   it_pos_amt        = lt_pos_amt ).

  ENDMETHOD.

Calling the BAPI:

  METHOD post_document.

    DATA lt_return            TYPE STANDARD TABLE OF bapiret2.

    IF gs_sel-p_test = abap_true.
      gr_listlog->append_log_entry( iv_type = gr_listlog->gc_log_type_info
                                    iv_text = |Testlauf: Keine Belegbuchung|
                                    iv_alog = abap_true ).
      RETURN. "Im Testlauf hier verlassen
    ENDIF.

    SET UPDATE TASK LOCAL.

    CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST'
      EXPORTING
        documentheader = is_documentheader
      TABLES
        accountgl      = it_pos
        currencyamount = it_pos_amt
        return         = lt_return.

    "Protokollzeilen mit BAPI Meldungen hinzufügen
    LOOP AT lt_return ASSIGNING FIELD-SYMBOL(<ls_return>).
      gr_listlog->append_log_entry( iv_type = <ls_return>-type
                                    iv_text = CONV #( <ls_return>-message )
                                    iv_alog = abap_true ).
    ENDLOOP.

    "Prüfen, ob eine Fehlermeldung vorliegt
    IF line_exists( lt_return[ type = 'A' ] ) OR line_exists( lt_return[ type = 'E' ] ).
      "Rollback
      CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
    ELSE.
      "Alles gut -> commit
      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
        EXPORTING
          wait = 'X'.

      "Protokollzeile mit der Erzeugten Belegnummer nochmal explizit ins Log
      DATA(lv_documentnumber) = lt_return[ 1 ]-message_v2(10). "hier steht laut Doku die Belegnummer drin
      gr_listlog->append_log_entry( iv_type = gr_listlog->gc_log_type_success
                                    iv_text = |Belegnummer: { lv_documentnumber }|
                                    iv_alog = abap_true ).
    ENDIF.

  ENDMETHOD.

[ABAP] Clean Code

ABAP Clean Code


DRY – Don’t repeat yourself

KISS – Keep it simple, stupid

YAGNI – You ain’t gonna need it

PEBKAC – Problem Exist Between Keyboard And Chair

SoC – Separation of concerns


Issues generally come in three forms:

  1. syntax errors that prevent a program from running
  2. runtime errors when code fails to execute or has unexpected behavior
  3. semantic (or logical) errors when code doesn’t do what it’s meant to