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

[SAPUI5] Suppress default oData error message / display meaningful error messages

Create a separate ErrorHandler.js file, like it is described here and either do your own error handler implementation, or take the sample from here. To avoid displaying multiple errors at once, follow this chapter.

Thanks to the provided dsag sample, this is takes only a few minutes and improves the user experience a lot!

[ABAP] xsdbool

Somehow I always forget that there is a boolean function in ABAP. That’s why I’m writing this post to hopefully remember it better. 🙂

If you just want to check something for truthiness, you can do it in the following three ways:

IF sy-subrc = 0.
  result = abap_true.
ELSE.
  result = abap_false.
ENDIF.
result = SWITCH #( sy-subrc WHEN 0 THEN abap_true
                                   ELSE abap_false ).
result = xsdbool( sy-subrc = 0 )

[CAP] Select max with group by

https://www.w3resource.com/sql/aggregate-functions/Max-with-group-by.php

https://answers.sap.com/questions/13081527/simple-count-aggregation-on-caps-cql.html?childToView=13079907&answerPublished=true

entity myEntity {
        key ID: Integer;
        key seqNr: Integer;
        key createdAt: DateTime;
        ...
    }

@readonly
entity myEntityMaxSeqNr 
        as select from myEntity {
            ID, 
            count(seqNr) as maxSeqNr: Integer
            createdAt,
            ...
            } 
        group by 
            ID,
            createdAt;

This can also be done using CQL like here.

[SAPUI5] Create date object in UTC YYYY-MM-ddTHH:mm:ss

https://sapui5.hana.ondemand.com/#/api/sap.ui.core.format.DateFormat%23methods/format

            const today = new Date()
            const oDateTimeFormat = sap.ui.core.format.DateFormat.getDateTimeInstance({
                pattern: "yyyy-MM-ddTHH:mm:ss",
                UTC: true
            })
            const todayISO = oDateTimeFormat.format(today)

The UTC flag can also be set, when calling the format function.

            const today = new Date()
            const oDateTimeFormat = sap.ui.core.format.DateFormat.getDateTimeInstance({
                pattern: "yyyy-MM-ddTHH:mm:ss",
                //UTC: true
            })
            const todayISO = oDateTimeFormat.format(today, true)

[SAPUI5] Adding Lanes to a Process Flow

Manually adding Lanes to a Process Flow Control:

https://sapui5.hana.ondemand.com/#/api/sap.suite.ui.commons.ProcessFlow
https://sapui5.hana.ondemand.com/#/api/sap.suite.ui.commons.ProcessFlowLaneHeader
https://sapui5.hana.ondemand.com/#/entity/sap.suite.ui.commons.ProcessFlow/sample/sap.suite.ui.commons.sample.ProcessFlowUpdateLanes/code

In my case, there was no way to bind the model to the view, so I did the mapping for each ProcessFlowLaneHeader in the callback function after reading the oData entity.

view.xml

<flow:ProcessFlow id="process-flow"/>

controller.js

var oProcessFlow = this.getView().byId("process-flow")

var oRequestFilter = new sap.ui.model.Filter({
    path: "myId",
    operator: sap.ui.model.FilterOperator.EQ,
    value1: myId
})

this.getView().getModel().read("/WorkflowSet", {
    filters: [oFormularIdFilter],
    success: (oData, response) => {
        for (var i = 0; i < oData.results.length; i++) {
            var oLaneHeader = new ProcessFlowLaneHeader({
                laneId: oData.results[i].LaneId,
                iconSrc: oData.results[i].IconSrc,
                text: oData.results[i].Text,
                position: oData.results[i].Position,
                state: [{state: oData.results[i].State, value: "100"}]
            });
            oProcessFlow.addLane(oLaneHeader)
        }
    },
    error: oError => {
        sap.m.MessageToast.show("An error occured while reading entity /WorkflowSet.")
    }
});

[SuccessFactors] Process Trigger

In a Process Trigger, you can get a good overview of an employee who moved from REC, via ONB to EC.

Manage Data -> Search -> Process Trigger

This information can also be fetched via API.

API Entity: ONB2Process

### Process Trigger
GET {{$dotenv sf_api_url}}/odata/v2/ONB2Process('06B129C95FD3482B851018D37B697149')
Authorization: Basic {{$dotenv sf_api_auth_base64}}
Accept: application/json

### processTriggerNav, includes rcmCandidateId, rcmApplicationId, rcmJobReqId
GET {{$dotenv sf_api_url}}/odata/v2/ONB2Process('06B129C95FD3482B851018D37B697149')
?$expand=processTriggerNav
Authorization: Basic {{$dotenv sf_api_auth_base64}}
Accept: application/json

[Fiori Elements] Custom Column in a Table is not visible

I had a generated Fiori Elements App (done by using @sap/generator-fiori), containing a List, where I needed to add a custom column containing a Button. I found this well explained in the official documentation:

https://sapui5.hana.ondemand.com/#/topic/d525522c1bf54672ae4e02d66b38e60c

I followed the instructions exactly, but it didn’t work. When comparing my manifest.json again with the example, I noticed one minor difference. In my generated App, there was an extra items/ in front of the @com.sap.vocabularies.UI.v1.LineItem.

My generated App
The manifest.json sample

After removing items/ the custom column was suddenly visible. When I noticed the difference, I thought that would never be the reason. Luckily, I tested it after all. That really is a big problem with Fiori Elements. These are problems that can no longer be solved by debugging or similar.

Here some more helpful links, when challenging with a custom column:

https://github.com/SAP-samples/fiori-elements-feature-showcase/blob/main/README.md#add-custom-column-extensibility

https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/customElements/customColumnContent

[ABAP] SALV – Access column name

  TRY.
      cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lo_alv)
                              CHANGING  t_table      = lt_output ).
    CATCH cx_salv_msg INTO DATA(lx_salv).
      WRITE: / lx_salv->get_text( ).
  ENDTRY.

  DATA(columns) = lo_alv->get_columns( ).
  DATA(lt_cols) = columns->get( ).

  LOOP AT lt_cols INTO DATA(ls_cols).
    DATA(lo_column) = ls_cols-r_column.
    CASE ls_cols-columnname.
      WHEN 'MANDT'
        lo_column->set_visible( abap_false ).
    ENDCASE.
  ENDLOOP.