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

[ABAP] Read E-Mail-Template

Addition to https://nocin.eu/abap-e-mail-templates-in-s-4hana/

I had to create an E-Mail template where I did not need a CDS view or any variable at all. I simply needed the defined mail template without any rendering of class cl_smtg_email_api.
Solution: Reading the plain mail template can be achieved using class cl_smtg_email_template and method get_tmpl_cont:

DATA(ls_mail_content) = cl_smtg_email_template=>get( p_mailtx )->get_tmpl_cont( iv_langu = 'D' ).

Full sample:

 PARAMETERS: p_mailtx TYPE smtg_tmpl_id OBLIGATORY.
   
 TRY.
        " get mail template
        DATA(ls_mail_content) = cl_smtg_email_template=>get( p_mailtx )->get_tmpl_cont( iv_langu = 'D' ).

        " optional: dynamic manipulation of html email body

        " create mail document
        DATA(lo_mail_document) = cl_document_bcs=>create_document( i_type    = 'HTM'
                                                                   i_subject = conv #( ls_mail_content-subject )
                                                                   i_text    = cl_bcs_convert=>string_to_soli( ls_mail_content-body_html ) ).

        " create Sender & Receiver
        DATA(lo_sender)    = cl_cam_address_bcs=>create_internet_address( i_address_string = 'noreply@example.com'
                                                                          i_address_name   = 'Test' ).

        DATA(lo_recipient) = cl_cam_address_bcs=>create_internet_address( i_address_string = 'max.mustermann@example.com').

        " create Business Communication Service
        DATA(lo_bcs) = cl_bcs=>create_persistent( ).
        lo_bcs->set_document( lo_mail_document ).
        lo_bcs->set_sender( lo_sender ).
        lo_bcs->add_recipient( lo_recipient ).
        lo_bcs->send( ).
        COMMIT WORK.

      CATCH cx_smtg_email_common INTO DATA(ls_cx).
        DATA(lv_message) = ls_cx->get_text( ).
        MESSAGE e899(id) WITH 'Unable to send message:'(004) lv_message.
    ENDTRY.

[ABAP] Quick way to get last year’s BEGDA and ENDDA

Using method get_current_year of class cl_hcmfab_reporting_utility you can get BEGDA and ENDDA of the current year, e.g. 01.01.2025 and 31.12.2025

  CALL METHOD cl_hcmfab_reporting_utility=>get_current_year
    EXPORTING
      iv_date  = sy-datlo
    IMPORTING
      ev_begda = DATA(begda)
      ev_endda = DATA(endda).

I couldn’t find a similar method to get the same for the last year. But I could solve the problem with three simple lines.

DATA(last_year) = conv d( sy-datlo - 365 ).
DATA(begda)     = last_year(4) && '0101'.
DATA(endda)     = last_year(4) && '1231'.

After that, I asked Perplexity and it gave me a similar result.

DATA(lv_last_year) = sy-datum+0(4) - 1.
DATA(lv_begda)     = |{ lv_last_year }0101|.
DATA(lv_endda)     = |{ lv_last_year }1231|.

Using this method, you could even reduce it to two lines, and it would still be easy to read.

DATA(begda)  = |{ sy-datum(4) - 1 }0101|.
DATA(endda)  = |{ sy-datum(4) - 1 }1231|.

[ABAP] Ermittle Sachkonto zu symbolischen Konto aus FI System

DATA(service_manager) = NEW cl_hrpp_ws_service_manager( ).

SELECT * INTO TABLE @DATA(lt_t52el) FROM t52el  WHERE molga = '01' AND symko <> @space AND endda >= @pn-begps. " Verknüpfung Lohnart zu symbolischen Konto
SELECT * INTO TABLE @DATA(lt_t52ek) FROM t52ek.                                                                " Symbolische Konten
SELECT * INTO TABLE @DATA(lt_t52ep) FROM t52ep.                                                                " Kontierungsarten

 LOOP AT lt_t52el INTO DATA(ls_t52el). " Ermittle je Lohnart die symbolischen Konten (1:n)

      TRY.
          DATA(ls_t52ek) = lt_t52ek[ symko = ls_t52el-symko ].   " Ermittele Kontierungsart
          DATA(ls_t52ep) = lt_t52ep[ koart = ls_t52ek-koart ].   " Ermittele Typ des symbolischen Kontos
          DATA(process)  = CONV ktosl( 'HR' && ls_t52ep-kttyp ).
        CATCH cx_sy_itab_line_not_found.
          CONTINUE.
      ENDTRY.

      service_manager->hrpp_fi_acct_det_hr( EXPORTING companycode        = pernr-bukrs
                                                      process            = process              " Vorgangsschlüssel
                                                      symb_acct          = ls_t52el-symko
                                                      eg_acct_det        = CONV #( '1' )        " Überleitung FI/CO: Mitarbeitergruppierung Kontenfindung: alle Mitarbeiter
                                            IMPORTING gl_account_debit   = DATA(account_debit)
                                                      gl_account_credit  = DATA(account_credit)
                                                      return_tab         = DATA(return_tab) ).
      IF line_exists( return_tab[ type = 'E' ] ).
        CONTINUE.
      ENDIF.

      " Lese Sachkonto Text
      service_manager->hrpp_gl_acc_getdetail( EXPORTING companycode    = pernr-bukrs
                                                        glacct         = account_debit
                                                        language       = sy-langu
                                                        text_only      = abap_true
                                              IMPORTING account_detail = DATA(account_detail) ).

 ENDLOOP.

[ABAP] OData Message Container

When dealing with standard HCM Fiori Applications, it can be handy to provide custom error messages when adding additional checks. This can easily be done using the message container.

        DATA(lo_message_container) = mo_context->get_message_container( ).
        lo_message_container->add_messages_from_bapi( it_bapi_messages          = VALUE #( ( type = 'E' message = 'This is a custom error.' ) )
                                                      iv_determine_leading_msg  = /iwbep/if_message_container=>gcs_leading_msg_search_option-last
                                                      iv_add_to_response_header = abap_true ).
        RAISE EXCEPTION NEW /iwbep/cx_mgw_busi_exception( ).