l_result = nmin( val1 = 10 val2 = 20 ). " = 10
l_result = nmax( val1 = 10 val2 = 20 ). " = 20
Category: SAP
SAP
[SAPUI5] MyInbox: Integration of Detail View – EmbedIntoDetail
https://launchpad.support.sap.com/#/notes/2305401 (App to App Navigation CookBook.pdf)
https://blogs.sap.com/2020/07/31/fiori-my-inbox-integration-of-custom-detail-page/
Target:
Go to /n/ui2/fpld_cust and define a second target for your App, i.e. approve.

The approve target needs the “emdedIntoDetails” parameter:

SWFVISU:
Add the new target for your WF Task. Here you have access to all attributes of your Workitem-Container. Pass all your mandatory fields you’ve defined in your oData Entity.
Some examples: https://blogs.sap.com/2016/05/31/my-inbox-open-task-swfvisu-configuration/

If your missing some parameters, just add them in your Workitem Task and pass the values directly into it right from your Workflow Container. This looks much better.

Manifest:
Add a route to navigate via Inbox. The pattern has to match your inbox url.

"routes": [
{
"pattern": "",
"name": "master",
"target": "master"
},
{
"pattern": "DataSet/{Pernr},{Datum},{Infty}",
"name": "object",
"target": [
"master",
"object"
]
},
{
"pattern": "detail/LOCAL_INBOX/{wfInstanceId}/{taskPath}",
"name": "wfobject",
"target": "object"
}
Detail.Controller:
onInit: function () {
// Model used to manipulate control states. The chosen values make sure,
// detail page is busy indication immediately so there is no break in
// between the busy indication for loading the view's meta data
var oViewModel = new JSONModel({
busy: false,
delay: 0
});
this.getRouter().getRoute("object").attachPatternMatched(this._onObjectMatched, this);
//My Inbox Integration
this.getRouter().getRoute("wfobject").attachPatternMatched(this._onWFObjectMatched, this);
this.setModel(oViewModel, "detailView");
this.getOwnerComponent().getModel().metadataLoaded().then(this._onMetadataLoaded.bind(this));
},
_onWFObjectMatched: function (oEvent) {
this.getModel("appView").setProperty("/layout", "MidColumnFullScreen");
var compData = this.getOwnerComponent().getComponentData();
if (compData && compData.startupParameters && compData.startupParameters.PERNR && Array.isArray(compData.startupParameters.PERNR) &&
compData.startupParameters.PERNR[0]) {
var sPernr = compData.startupParameters.PERNR[0];
var sDatum = compData.startupParameters.DATUM[0];
var sInfty = compData.startupParameters.INFTY[0];
this.byId("detailPage").addStyleClass("myInboxPage");
this.getModel().metadataLoaded().then(function () {
var sObjectPath = this.getModel().createKey("/DataSet", {
Pernr: sPernr,
Datum: sDatum,
Infty: sInfty
});
this._bindView(sObjectPath);
}.bind(this));
}
},
[SAPUI5] uncheck checkbox if another one is selected
XML
<Checkbox id="Checkbox1" selected="{ path:'oModel>CB1' }" select="handleOrderSelected"></Checkbox>
<Checkbox id="Checkbox2" selected="{ path:'oModel>CB2' }" select="handleRejectSelected"></Checkbox>
controller.js
handleOrderSelected: function (oEvent) {
//Wenn Checkbox1 selektiert, setze Checkbox2 auf false.
var bSelected = oEvent.getParameter("selected");
if (bSelected) {
var bindingContext = oEvent.getSource().getBindingContext("oModel");
this.oModelTemplate.setProperty("CB2", "", bindingContext, false);
}
},
handleRejectSelected: function (oEvent) {
//Wenn Checkbox2 selektiert, setze Checkbox1 auf false.
var bSelected = oEvent.getParameter("selected");
if (bSelected) {
var bindingContext = oEvent.getSource().getBindingContext("oModel");
this.oModelTemplate.setProperty("CB1", "", bindingContext, false);
}
}
[ABAP] Get month name
METHOD get_month_name.
DATA: month_names TYPE TABLE OF t247.
CALL FUNCTION 'MONTH_NAMES_GET'
TABLES
month_names = month_names
EXCEPTIONS
OTHERS = 0.
TRY.
r_name = month_names[ mnr = i_month ]-ltx.
CATCH cx_sy_itab_line_not_found.
ENDTRY.
ENDMETHOD.

[SAPUI5] Copy Table Row
Button für das Kopieren einer Zeile hinzufügen.
<Table id="itemsTable" items="{oModel>/ITEMS}">
<columns>
<Column id="splitColumn" hAlign="Center" demandPopin="false">
<Text text="{i18n>SPLIT}"/>
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<Button press="onSplitPressed" id="SPLIT_ROW" icon="{= ${oModel>CUSTOM_ITEM} === true ? 'sap-icon://delete' : 'sap-icon://add'}"/>
</cells>
</ColumnListItem>
</items>
</Table>
Nur neu hinzugefügte Zeilen sollen auch wieder gelöscht werden dürfen, daher werden manuell hinzugefügte Zeilen markiert mit CUSTOM_ITEM = True;
Via Expression Binding wird dann das erforderliche Icon bestimmt.

onSplitPressed: function (oEvent) {
var oContext = oEvent.getSource().getBindingContext("oModel");
var path = oContext.getPath();
var oModel = oContext.getModel();
var oItems = oModel.getProperty("/ITEMS");
var index = path.substr(path.length - 1);
//selektiertes Item lesen
var oItem = oModel.getProperty(path);
//was soll passieren? Zeile hinzufügen oder entfernen?
if (oItem.CUSTOM_ITEM !== true) {
//Neues Item anlegen
var oNewItem = JSON.parse(JSON.stringify(oItem));
//Markiere neue Zeile, da nur diese auch wieder gelöscht werden darf
oNewItem.CUSTOM_ITEM = true;
// +1 weil Zeile soll ja nach der Aktuellen einfügt werden
index++;
oItems.splice(index, 0, oNewItem);
} else {
// Item löschen
oItems.splice(index, 1);
}
oModel.setProperty("/ITEMS", oItems);
},
[ABAP] ALV column header
DATA: o_salv TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = o_salv
CHANGING t_table = l_lines ).
LOOP AT o_salv->get_columns( )->get( ) REFERENCE INTO DATA(l_column).
DATA(lo_column) = CAST cl_salv_column( l_column->r_column ).
lo_column->set_fixed_header_text( 'L' ).
ENDLOOP.
o_salv->get_columns( )->get_column( 'TEST1' )->set_long_text( 'Test1 Header' ).
o_salv->get_columns( )->get_column( 'TEST2' )->set_long_text( 'Test2 Header' ).
o_salv->get_columns( )->get_column( 'TEST1' )->set_output_length( 30 ). "to increase the column width
[Fiori] Debug deployed Fiori App
When opening the Dev-Tools for a deployed Fiori App, it will look like this:

You won’t see any controller.js to debug.
What to do? Close the Debugger-Tools and hit CTRL+ALT+SHIFT+P to open the Technical Information Dialog

Check the Checkbox (or choose a specific controller) and reload the app.


It reloads with a new URL parameter and if you open the Dev-Tools, you will now see the controller.js.

Other options to debug or at least to collect some information about your app are the UI5 Diagnostics (hit CTRL+ALT+SHIFT+S) and the UI5 Inspector which is a Brower Addon.
[HR] Infotype – add PBO or PAI logic
There are many ways to add custom logic when processing an Infotype. Here are just a few:
SMOD
PBAS0001
PBAS0002

ZXPADU01 – when an infotype is called
ZXPADU02 – when an action is performed on an infotype
https://regotz.jimdofree.com/abap/dynpro/infotypen-pai-pbo/
BAdI’s
- HRPAD00INFTY (method IN_UPDATE) is called by the old infotype framework (PA30, SAP50UPR)
- HRPAD00INFTYDB (method UPDATE_DB) is called in the decoupled infotype framework
BAdI: HRPAD00INFTY – Verbucher / Infotyp-Pflege


BAdI: HRPAD00INFTYDB – HR: Stammdaten, Infotype DB Update Logik
“The BAdI is called, after the decoupled infotype framework writes the infotype data to the database. This is done during method FLUSH.”
Note: The Infotypes 2000-2999 are not decoupled yet! More here and here.


