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

[SuccessFactors] Insert balances via TimeAccountDetail API

I had the task to insert additional vacation days to the TimeAccount of some employees. To do this, you have to insert some new entries in the related TimeAccountDetail entity.

The official documentation states that you can create a TimeAccountDetail via UPSERT, and there is even an example. A very bad formatted example….

But to me, it was unclear, what I have to provide as externalCode. Obviously, TimeAccount_externalCode required the externalCode of the TimeAccount, which the entry should belong to. But I was expecting that the TimeAccountDetail externalCode should be created, when UPSERTing the entry. Somehow the documentation is missing some explanation here… But in the note 2243841 I found the missing hint:

While using API calls, Successfactors system would not generate unique external Code for TimeAccountDetail API. You will have to explicitly provide external code which should be unique.

Ok, so simply provide a random externalCode. Following my UPSERT Request:

### The related TimeAccount, where the entry should belong to. Can be fetched via another API call
@TimeAccount_externalCode=aac183cdc57242cb9f7454131f0da069

### Create a random TimeAccountDetail externalCode 
@externalCode=70b54990b44440fab4c5084c971cc744

### Insert balances
GET {{$dotenv sf_api_url}}/odata/v2/upsert
Authorization: Basic {{$dotenv sf_api_auth_base64}}
Accept: application/json
Content-Type: application/json

{ 
  "__metadata" : {
    "uri" : "http://my-sf-demo-api-server/odata/v2/TimeAccountDetail(TimeAccount_externalCode='{{TimeAccount_externalCode}}',externalCode='{{externalCode}}')", 
    "type" : "SFOData.TimeAccountDetail"
  },
  "TimeAccount_externalCode" : "{{TimeAccount_externalCode}}", 
  "externalCode" : "{{externalCode}}", 
  "bookingUnit" : "DAYS", 
  "bookingType" : "MANUAL_ADJUSTMENT", 
  "bookingDate" : "\/Date(1747872000000)\/", 
  "bookingAmount" : "1", 
  "comment" : "Urlaub"
}

But what ever I tried as externalCode, it always failed…

In note 2243841, there is also the last sentence:

We generally do not suggest to use Upsert operation for TimeAccountDetail OData API due to external code limitation.

This confused me even more, but as the note is from 2016, I thought it could be outdated, and the official API documentation is correct. But it seems the opposite is right….
When trying a normal POST instead of an UPSERT, it immediately worked.

### The related TimeAccount, where the entry should belong to. Can be fetched via another API call
@TimeAccount_externalCode=aac183cdc57242cb9f7454131f0da069

### Create a random TimeAccountDetail externalCode 
@externalCode=70b54990b44440fab4c5084c971cc744

### Insert balances
POST {{$dotenv sf_api_url}}/odata/v2/TimeAccountDetail
Authorization: Basic {{$dotenv sf_api_auth_base64}}
Accept: application/json
Content-Type: application/json

{ 
  "TimeAccount_externalCode" : "{{TimeAccount_externalCode}}", 
  "externalCode" : "{{externalCode}}", 
  "bookingUnit" : "DAYS", 
  "bookingType" : "MANUAL_ADJUSTMENT", 
  "bookingDate" : "\/Date(1747872000000)\/", 
  "bookingAmount" : "1", 
  "comment" : "Urlaub"
}

Not sure if I did something wrong when using UPSERT, but why should I even use an UPSERT, if I can simply use a normal POST request. Once again, poor SAP documentation has cost me a lot of my lifetime…

[CAP] CQL Expand two levels deep

I’ve already made a post about expanding compositions or associations (see here), but this time I had to extend two levels deep.

My entity structure looked something to this:

entity Header: cuid, managed {
    Items           : Composition of many Header.Items
                          on Items.purgeRun = $self;
}

entity Header.Items : cuid, managed {
    file            : Association to Files @mandatory @assert.target;
    header: Association to Header;
}

entity Files : cuid, managed {          
    content         : LargeBinary @Core.MediaType: mediaType  @Core.ContentDisposition.Filename: fileName  @Core.ContentDisposition.Type: 'inline';
    mediaType       : String      @Core.IsMediaType: true;
    fileName        : String      @mandatory;
    size            : Integer;
}   

It is possible to query all data in a single HTTP call using $expand twice.

### Header + Items + File
GET {{server}}/odata/v4/service/MainEntity/{{ID}}
?$expand=Items($expand=file)
Authorization: Basic {{username}} {{password}}

However, if you want to fetch the same data using CQL, the following query is required:

        const data = await SELECT(Header, ID)
            .columns(h => {
                h('*')
                h.Items(i => {
                    i('*')
                    i.file(f => f('*'))
                })
            })

This syntax is really hard to remember…

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

[SAP] System upgrade – Find related notes

Brief overview of how to find all notes contained in the installed SPs during a system patch.

First, look up the new SP level for a specific component. For example, if the old SP level was 0026 and the patch it is 0028, you need to check the notes for SP 0027 and 0028.

Then open the SAP Software center: https://me.sap.com/softwarecenter (or via https://support.sap.com/en/index.html and click on Software Downloads)

Search for component UIHR002

Click on “Maintenance Software Component”

Click on “SUPPORT PACKAGES”

Choose a package you want to view the notes for and click on “Content Info”

Now it will list all notes which are included

[SAP] Initiale Dinge, die ich für jeden neuen SAP Gui Zugang erledige

Das System in KeePass hinzufügen, für die 1-Klick Anmeldung.

Meine Favoriten importieren. (Man kann übrigens einfach Favoriten über das Kommandofeld hinzufügen via %_GCADDF, technisch liegen die Favoriten in der Tabelle SMEN_BUFFC)

Unter Zusätze → Einstellungen (Umschalt + F9) die Einstellungen öffnen und “Technische Namen anzeigen” anhaken

Unter Optionen das Theme von Belize auf Blue Crystal abändern und eine Systemfarbe einstellen

sowie Schlüssel in Dropdown-Listen anzeigen

In der SE11 über Hilfsmittel → Benutzerdefinierte Einstellungen → Data Browser → Ausgabenliste die ALV-Grid-Darstellung aktivieren

In der SE80 über Hilfsmittel → ABAP Editor → Pretty Printer die folgenden Einstellungen setzen

[HR] Buchungsbelege anzeigen/analysieren

Hilfreiche Reports:

  • SAPMPCP0 – Buchungsläufe bearbeiten (TCode PCP0)
  • H99CWTR0 – Lohnarten Reporter
  • RPCIP_DOCUMENT_ANALYSE – Buchungsbelege analysieren
  • RPCIPD00_FRAME – Details zu Belegzeilen anzeigen

Einige relevante Tabellen:

  • PPDHD – Überleitung FI/CO: Kopf des Belegs
  • PPDIT – Überleitung FI/CO: Zeilen des HR-Zwischenbelegs
  • PPDIX – Überleitung FI/CO: Indextabelle der HR-Zwischenbelege (Verknüpfung zwischen PPDIT und PPOIX)
  • PPDST – Überleitung FI/CO: Substituierte Kontierungsobjekte
  • PPOIX – Index Abrechnungsergebniszeile -> Buchungszeile
  • PPOPX – Index alte <-> neue Belegzeile für ‘P’-Ergebnisse
  • PEVST – Abrechnungsauswertungsläufe
  • PEVAT – Attribute von Auswertungsläufen
  • PEVSH – Historie von Abrechnungsauswertungsläufen (STATUS = 40 Überleitung an FI)

Die Klasse CL_DOCUMENT_ANALYSE hilft die Verknüpfung der Tabellen zu verstehen