nocin.eu

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

[Fiori] Creating a Launchpad Plugin using BAS

Since there is no Wizard anymore for creating a Launchpad Plugin, as there was in WebIDE, you have to create it manually. The following two guides helped me create a Launchpad Plugin in BAS from scratch:
https://github.com/SAP-samples/fiori-custom-plugin-abap/tree/main
https://github.com/SAP-samples/launchpad-service-samples
In my scenario, I had to deploy to a normal S/4 HANA system, so I skipped all the Steampunk or WorkZone parts.

In the first sample, for some reason they use jQuery to call an OData Service, in the second sample no OData is called at all. But of course, an OData Service can be used in a Plugin the same way as you do in every other Fiori App. You just have to add your service in the manifest.json like you would normally do:

  "sap.app": {
    ...
    "dataSources": {
      "ZFLP_TEST_SRV": {
        "uri": "/sap/opu/odata/sap/ZFLP_TEST_SRV",
        "type": "OData",
        "settings": {
          "odataVersion": "2.0",
          "localUri": "localService/metadata.xml"
        }
      }
    }
  },
  ...
  "sap.ui5": {
    ...
    "models": {
      "": {
        "dataSource": "ZFLP_TEST_SRV",
        "preload": true,
        "settings": {
          "defaultCountMode": "Inline",
          "metadataUrlParams": {
            "sap-documentation": "heading"
          }
        }
      }
    }

And for i18n

  "sap.ui5": {
     ...
    "models": {
      "i18n": {
        "type": "sap.ui.model.resource.ResourceModel",
        "settings": {
          "bundleName": "ne.flp.plugin.flp_my_plugin.i18n.i18n"
        }
      }
    }

To activate the deployed Plugin, use these transactions:

  • /ui2/flp_conf_def → Define FLP Plugins → Create new entry
  • /ui2/flp_sys_conf → Make Plugin available system-wide
  • /ui2/flp_cus_conf → Make plugin available in specific clients
  • /ui2/flp → open Fiori Launchpad to test plugin

[CAP] Parses a string in CQL expression and add it as WHERE condition

https://cap.cloud.sap/docs/node.js/cds-compile#cds-parse-xpr

Some examples:

// equal
cds.parse.xpr (`lastName = 'Naidoo'`)

// or
cds.parse.xpr (`lastName = 'Naidoo' or firstName = 'Verónica'`)

// in
cds.parse.xpr (`lastName IN ('Naidoo','González Esteban')`) 

How to add an expression as where condition:

    srv.before('READ', EntityName, async req => { 

        const cxn  = cds.parse.xpr (`lastName = 'Naidoo'`) 

        req.query.SELECT.where ??= []
        if (req.query.SELECT.where.length > 0) {
            req.query.SELECT.where.push("and")
        }
        req.query.SELECT.where.push(...cxn)

    })

[ABAP] Get MOLGA for PERNR

" Option 1
TRY.
    cl_hrpa_masterdata_factory=>get_read_molga( IMPORTING read_molga = DATA(lr_molga) ).
    DATA(molga) = lr_molga->read_molga_by_pernr( pernr ).
  CATCH cx_hrpa_violated_assertion.
ENDTRY.

" Option 2
TRY.
    DATA(employee_api) = cl_hcmfab_employee_api=>get_instance( ).
    DATA(molga)        = employee_api->get_molga( pernr ).
  CATCH cx_hcmfab_common.
ENDTRY.

[ABAP] xstring to binary (RAW)

* Option 1
  DATA lt_data TYPE STANDARD TABLE OF x255.
  CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
    EXPORTING
      buffer     = lv_xstring
    TABLES
      binary_tab = lt_data.

* Option 2
  cl_scp_change_db=>xstr_to_xtab( EXPORTING im_xstring = lv_xstring
                                  IMPORTING ex_xtab    = DATA(lt_data) ).

* Option 3
  DATA(lt_data) = cl_bcs_convert=>xstring_to_solix( lv_xstring ).

[Fiori] My Inbox – Tasks not appearing in Inbox

There are many reasons why a workflow task might not appear in the Inbox app. One reason I always forget to check is quite simple.

Check whether a scenario is configured!

Simply open the Tile configuration and check the Parameter field. If there is a scenario, it would be something like scenarioId=EHS_HS_HAZMAT instead of allItems=true.

If a scenario is in use, you can find more about it in the customizing here:

In a scenario, a restriction to certain workflow tasks can be configured.

More information can be found here:
https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/8308e6d301d54584a33cd04a9861bc52/68c4379a35f644f6b3a73428594d6c3f.html?locale=en-US&version=LATEST
https://community.sap.com/t5/technology-blog-posts-by-sap/sap-fiori-for-sap-s-4hana-fiori-my-inbox-part-1-activation/ba-p/13326175

[Home Assistant] Sciencer smart lock V1 Pro+

I always wanted to try one of these cheap Smart Locks from AliExpress. In November, I saw a good offer and ordered one. Most of these Smart Locks have Bluetooth and can be connected to Wi-Fi using an extra hub. Depending on the lock version, it can either be used with the Tuya App or the TTLock App. In some comments I’ve read, that TTLock is the better way, when planing to integrate the lock in Home Assistant.

Additionally, in some comments that I don’t find anymore, someone wrote that the new G6 Hub supports Matter, and this way the lock can be added locally to Home Assistant, instead of the TTLock Cloud based service. But only one lock per Hub can be published via Matter. I found no information what entities will be published by the Hub via Matter. That’s why I ordered one and tested myself.

I bought the following two devices:

Sciener smart lock V1 Pro+ for 50,95$ in the TTLock version without Gateway

Smart Lock Matter Gateway G6 for 24,07$

Setup was super easy and the lock works perfectly fine! Setting up the hub and the TTLock app was also easy.

Here is a screenshot what I got after adding the Hub to Home Assistant via Matter.

This looked promising, but it turned out, nothing ever gets updated…. the only thing that updates occasionally is the lock.sciener_smart_lock control (second control in the screenshot), but most of the time it is in status unknown. Not sure what is going on here, but even is the status is not unknown, it stays in the status “unlocked” most of the time, even if the lock is currently locked. However, it is possible to unlock the door via Home Assistant, but most of the time you first have to hit Lock, although it is already locked, and then Unlock. But in daily use, you would rarely open the lock via Home Assistant anyway, as using the fingerprint is much quicker. However, for me, it was more important to monitor who and when unlocked the door, but this information is not provided.

As the Matter integration turned out to be a fail, I set up the TTLock integration, which depends on the cloud.

Using TTLock it is a similar situation. At least the lock control is always in status Locked, and the lock can be unlocked from Home Assistant, but the sensors are never updated and also there is no lock history. Means opening the lock using the fingerprint, does lead to any update in the Home Assistant lock history. So even the TTLock Integration does not provide any real value…

I guess the lock does not provide many updates to the hub to enhance the battery lifetime. This means monitoring the lock in Home Assistant is currently very limited. Anyway, the lock is a great improvement in our daily lives, and I already wonder how I managed to live without it all these years. 🙂

[Fiori] Abwesenheitsantrag in Inbox für nicht genehmigungspflichtige Abwesenheitsart

Kürzlich hatte ich die Situation, dass eine Führungskraft einen Abwesenheitsantrag in der Inbox hatte für eine Abwesenheitsart, die eigentlich nicht genehmigungspflichtig ist. Es hätte also gar kein Genehmigungsworkflow gestartet werden dürfen. Merkwürdigerweise war die beantragte Abwesenheit auch bereits im Infotyp verbucht. Auch konnte man den Antrag in der Inbox weder Ablehnen noch Genehmigen, beides lief auf ein Fehler.

Wie kam es also zu dieser Situation?

Der Mitarbeiter hatte einen Antrag mit einer genehmigungspflichtigen Abwesenheitsart gestellt, wie z.B. Urlaub.

Bevor der Genehmiger diesen Antrag bearbeitet hat, wurde der Antrag vom Antragsteller jedoch nochmal abgeändert. Dies ist über das Stift-Symbol möglich. Dabei wurde dann eine nicht genehmigungspflichtige Abwesenheitsart gewählt, wie z.B. Abbau Überzeit.

In diesem Fall wird der Antrag ohne Genehmigungsprozess durchlaufen und die Abwesenheit wird kurz darauf direkt in den Infotyp geschrieben durch den Verbucherreport.

Jedoch gab es ja bereits einen laufenden Workflow mit einem Workitem in der Inbox des Genehmigers und dieser wurde nicht beendet. Stattdessen wurde in dem Workitem sogar die beantragte Abwesenheitsart aktualisiert, obwohl für diese Abwesenheitsart ja gar keine Genehmigung erforderlich ist und sogar bereits in den Infotyp geschrieben war.

Auch in der Antragsdatenbank spiegelt sich das Problem wider. Der Antrag stand dort im Status ‘POSTED‘ und der Workflow-Status auf ‘STARTED‘.

Ich habe das Szenario dann mit einer Zweiten, nicht genehmigungspflichtigen Abwesenheitsart getestet, also Urlaub erfasst und vor Genehmigung die Abwesenheitsart geändert. Hier wurde jedoch der laufende Workflow korrekterweise beendet.

Als ich beide Abwesenheitsarten in der V_T554S_WEB verglichen habe, ist mir aufgefallen, dass bei der problembehafteten Abwesenheitsart ein Workflow gecustomized war, obwohl diese ja nicht genehmigungspflichtig ist. Der Workflow wurde jedoch nur verwendet, um eine Info-Mail zu versenden.

Die Workflow Checkbox ließ sich leider nicht deaktivieren (vermutlich weil es schon Anträge zu der Abwesenheitsart gibt). Aber es scheint, als führt dieses Workflowcustomizing dann zu Inkonsistenzen, wenn in einem laufenden Antrag von einer genehmigungspflichtigen Abwesenheitsart zu einer nichtgenehmigungspflichtigen gewechselt wird.

Dieser Post nur als Erinnerung, falls ich nochmal in so eine Situation laufe. Vielleicht habe ich dann die Chance, es zu verifizieren.