nocin.eu

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

[Fiori] Transactions and Reports

SE38:

  • /UI2/START_URL
  • /UI2/START_TCODE
  • /UI2/FLP_ADMIN_UI

SICF:

  • Frontend-Services: /sap/bc/ui5_ui5/sap/
  • Backend-Services: /sap/opu/odata/sap/ und /sap/bc/bsp/sap/

Tcodes:

sicfPflege des HTTP-Service-Baums
(SAP Internet Communication Framework)
segwSAP Gateway Service Builder
/n/iwbep/view_logSAP Gateway Protokoll-Viewer
/n/iwfnd/gw_clientSAP Gateway Client
/n/iwfnd/apps_logSAP Gateway Anwendungsprotokoll-Viewer
/n/iwfnd/error_logSAP Gateway Fehlerprotokoll
/n/iwfnd/maint_serviceServices aktivieren und verwalten
/n/iwfnd/cache_cleanupBereinigung des Gateway-Modellcache (Frontend)
/n/ui2/custCustomizing für UI-Technologien
/n/ui2/flpSAP Fiori Launchpad
/n/ui2/flcSAP Fiori Launchpad – Prüfungen
/n/ui2/fliaFiori Launchpad: Absichtsanalyse
/n/ui2/flpd_custFiori Launchpad: Designer (mandantenüber.)
/n/ui2/flpd_confFiori Launchpad: Designer (mandantenabh.)
/n/ui2/flpcm/custFLP-Content-Manager
/n/ui2/flpcm/confFLP-Content-Manager
/n/ui2/semobjSemantisches Objekt definieren – Kunde
/n/ui2/semobj_sapSemantisches Objekt definieren – SAP
/n/ui2/theme_designerUI Theme Designer
swfvisuWorkflow Visualisierungs-Metadaten
swfvmd1Workflow Visualisierungs-Metadaten

[ABAP] Find employee subtitutes

cl_swl_substitution=>get_pers_substitutes( EXPORTING  i_substituted_person     = ls_substituted_person
                                                      i_start_date             = sy-datum
                                                      i_end_date               = sy-datum
                                           IMPORTING  et_substitutes           = DATA(lt_substitutes)
                                           EXCEPTIONS user_not_found           = 1 " Benutzer existiert nicht
                                                      plan_variant_not_found   = 2 " Planvariante ist nicht gepflegt
                                                      time_period_not_valid    = 3 " Zeitraum ungültig
                                                      no_personal_substitution = 4 " Es handelt sich um keine persönliche Vertretung
                                                      OTHERS                   = 5 ).

[ABAP] Leave Request Approval Workflow with Escalation

During the leave request approval process the standard workflow WS12300111 does not include any deadlines. To archieve this you can simply copy the workflow and add a deadline at the approval task (Step 38). There are two possible ways to forward the approval step to the next processor:
1. Forward your current workitem to the next approver.
2. Set current workitem to obsolete and create a new workitem and assign it to the next approver. Then you also have to add the new step ID to this BAdI Filter.
I took the first option. In my demo the escalation is triggered after just three minutes.

The deadline generates a new exit on the approval step.

In this new exit you able to call your own logic on finding the new approver, forward the workitem and inform him via mail if necessary.

To forward the request to next the approver, you have to forward the workitem and also set this new approver as next processor in the current leave request.
So first identify the next approver. I used RH_GET_LEADER for this.

*--------------------------------------------------*
* Get next approver
*--------------------------------------------------*
    CALL FUNCTION 'RH_GET_LEADER'
      EXPORTING
        plvar                     = '01'
        keydate                   = sy-datum
        otype                     = is_approver-otype
        objid                     = CONV realo( is_approver-objid )
      IMPORTING
        leader_type               = lv_leader_type
        leader_id                 = lv_leader_id
      EXCEPTIONS
        no_leader_found           = 1
        no_leading_position_found = 2
        OTHERS                    = 3.

    CHECK lv_leader_type EQ 'P' AND lv_leader_id IS NOT INITIAL.

    CALL FUNCTION 'HR_GET_USER_FROM_EMPLOYEE'
      EXPORTING
        pernr             = CONV pernr_d( lv_leader_id )
        iv_with_authority = abap_false
      IMPORTING
        user              = lv_userid_approver.

    ev_approver-otype = |US|.
    ev_approver-objid = lv_userid_approver.


Then set this new approver as next processor in your request. While doing this, it’s recommended to enqueue and dequeue the request. To get the current request object use class cl_pt_req_badi.

*--------------------------------------------------*
* Set new approver in request
*--------------------------------------------------*
    " Enqueue the request
    CALL FUNCTION 'ENQUEUE_EPTREQ'
      EXPORTING
        mode_ptreq_header = 'S'
        mandt             = sy-mandt
        request_id        = io_req->req_id
      EXCEPTIONS
        foreign_lock      = 1
        system_failure    = 2
        OTHERS            = 3.

    " Get the request object instance
    CALL METHOD cl_pt_req_badi=>get_request
      EXPORTING
        im_req_id  = io_req->req_id
      IMPORTING
        ex_request = DATA(lcl_request).
    CALL METHOD lcl_request->set_next_processor
      EXPORTING
        im_actor_type = 'P'
        im_plvar      = '01'
        im_otype      = 'P'
        im_objid      = CONV #( lv_leader_id ). " PERNR of Next Approver
    IF sy-subrc = 0.
      COMMIT WORK AND WAIT.
    ENDIF.

    " Dequeue the request
    CALL FUNCTION 'DEQUEUE_EPTREQ'
      EXPORTING
        mode_ptreq_header = 'S'
        request_id        = io_req->req_id.

Finally forward the workitem to the new approver. There of course you need the right workitem ID of the approving step.

*--------------------------------------------------*
* Forward workitem to next approver
*--------------------------------------------------*
    CALL FUNCTION 'SAP_WAPI_FORWARD_WORKITEM'
      EXPORTING
        workitem_id  = iv_wi_id                "woritem id of approving step
        user_id      = lv_userid_approver
        language     = sy-langu
        do_commit    = 'X'
      IMPORTING
        return_code  = lv_subrc.
    IF lv_subrc <> 0.
    ENDIF.

[Wireguard] Wireguard on Android

Update 11.05.2020: I recommend using the PiVPN script (especially when using a unprivileged container). https://nocin.eu/wireguard-set-up-wireguard-using-pivpn-inside-lxc/

In the F-Droid Store you’ll find the wireguard android app.

To get wireguard running, add a new peer to your server. So ssh into your sever (in my case an lxc on proxmox) and create a new key pair.

wg genkey | tee privatekey | wg pubkey > publickey

Now create the android.conf. Define the interface and add your server as peer.

[Interface]
PrivatKey = <android_privat_key>
Address = 192.168.1.3/24
DNS = 192.168.1.102
 
[Peer]
PublicKey = <server_public_key>
AllowedIPs = 0.0.0.0/0
Endpoint = my.doamin.org:51820
PersistentKeepalive = 25

Then add the new android peer to the server config.

[Peer]
PublicKey = <android_public_key>
AllowedIPs = 192.168.1.3/32

Now restart the wireguard interface to load the new config:

wg-quick down wg0
wg-quick up wg0

The fastest way to get your config on the android client is using a QR-Code. I used greencode for this.

apt install greencode
qrencode -t ansiutf8 < android.conf

Open your wireguard app, scan the QR-Code and connect to your server.

[Docker] Install JDownloader2 Headless

The first JDownloader installation in an Debian Stretch Linux Container I did manually following this guide. It was running stable since then. Now I wanted to upgrade to Debian Buster and to took the chance trying a Docker JDownloader installation. I already had a Debian Buster Container with Docker installed (look here for a short installation guide), so I just had do spin up the new JDownloader Docker like it is described here.
With parameter -v you are able to mount a specific download location inside Docker. I also added Port 3129 to enable MyJdownloader direct connection.

docker run -d \
    --name=jdownloader-2 \
    -p 5800:5800 \
    -p 3129:3129 \
    -v /docker/appdata/jdownloader-2:/config:rw \
    -v /mnt/nfs/downloads:/output:rw \
    jlesage/jdownloader-2

If you want JDownloader to autostart and forgot the “–restart” parameter during the “run” command (as I did), just use docker update:

docker update --restart always jdownloader-2 

[Wireguard] Configuring Wireguard in LXC

Update 11.05.2020: I recommend using the PiVPN script (especially when using an unprivileged container). https://nocin.eu/wireguard-set-up-wireguard-using-pivpn-inside-lxc/

I followed these three guides: 1, 2 and 3
First set folder permissions and genereate the first key pair inside your lxc.

umask 077
wg genkey | tee privatekey | wg pubkey > publickey

Then create the config file. Mine is called wg0.conf.
As address you can take whatever IP you want. I also added NAT to get internet access with the client through my container.
For the client you have to create on the client side a key pair and enter the public key in the server wg0.conf as peer. Now your config should have an interface and a peer part.

[Interface]
Address = 192.168.1.1/24
SaveConfig = true
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820
FwMark = 0xca6c
PrivateKey = <private_server_key>

[Peer]
#1. Peer Phone
PublicKey = <public_client_key>
AllowedIPs = 192.168.1.2/32

[Peer]
#2. Peer Notebook
PublicKey = <public_client_key>
AllowedIPs = 192.168.1.3/32

Then create the config on the client side. Mine is called client.conf. As peer we now enter our public server key.

[Interface]
PrivateKey = <private_client_key>
Address = 192.168.1.2/24
#this is my local pi-hole
DNS = 192.168.1.102                

[Peer]
PublicKey = <public_server_key>
AllowedIPs = 0.0.0.0/0
Endpoint = my.domain.org:51820
PersistentKeepalive = 25

That’s all we need. Now start the interface in your container, after that on the client.

wg-quick up wg0

To check the connection status just run:

wg show

I testet my connection with IP-Leak and ifconfig.me.

To stop the interface run:

wg-quick down wg0

To set up the VPN interface to be persistent across reboots, enable it as service:

sudo systemctl enable wg-quick@wg0.service