Just like for every IT system, for SAP BO / BI Platform you have a multi-system landscape: at least one a development system, and a productive one. Most often also a third system for testing and quality assurance. Applications are developed on the development system and then “transported” (SAP term) to test and productive systems. The word for this in the BO world is to “promote” the application.
If you have developed Lumira applications which are integrated tightly into the ‘application universe’, you have most probably linked from your app to other applications: other Lumira applications, but also Analysis for Office workbooks, maybe some legacy BEx reports running on the J2EE stack (enterprise portal), to SAP transactions on the ABAP stack accessed through WebGUI, or any other system. In most cases this linking from Lumira to other applications means opening a URL in a new browser tab by calling:
APPLICATION.openNewWindows("https:\\evosight.com\");
The challange is: from your Lumira application running on the development system, you would like to open another application also in the ‘development version’, for example on the CRM development system, while if your Lumira application is running on the productive BO system, you would like to open the URL pointing to CRM productive.
The “hardcode it and change it on every system” approach
What?! You are reading this paragraph despite of the word ‘hardcode’ in the title?! Shame on you – thats not what you learned at school! Changing the application manually every time after transporting it is a ticking time bomb: sooner or later someone will forget a URL. And it’s Charlie work anyway!
The “SAP must have a working solution for this” approach
Well that would be everyone’s first thought. This problem is so common, that SAP must have foreseen some simple way to manage it. Apparantly the did not. Looking for possible script methods you might have come across these ones:
APPLICATION.getDocumentInfo().id;
DS_LIST_COMPANY.getInfo().system;
CONNECTION_1.getSystem().name;
However, in case of a BW backend, the latter two will return “the CUID of the OLAP connection representing the backend system” (as stated also in the documentation.) The OLAP connection CUID however will typically be the same on all systems of the landscape. The application references the sytems of the datasources by this CUID, and when your transport the application, you will want this reference to work on the productive system as well. This is usally solved by having an OLAP connection with the same CUID on development, test and productive systems.
The username approach
You can query the user with the following code:
APPLICATION.getInfo().user;
Depending on the configuration of your BO system’s authentication schemes, this might return a plain username (like ‘USER1’) or a composite username which includes the system – for example ESD~001/USER1 – of you use the SAP authentication method to authenticate against the backend. In this case the ABAP system ID is part of the username and can be used to identify the system. The number 001 is the SAP client ID by the way.
The exit variable approach
There a simple but solid solution that should work in practically every case when you use a BW query as datasource. It will allow you to access the ABAP system ID the datasource is running on using a single line of script code.
For this, create a text variable of type customer-exit (not input-ready) in the BW system. The coding of the variable exit shall look something like this:
APPEND VALUE #( sign = 'I' opt = 'EQ' low = sy-sysid ) TO c_t_range.
Add this text variable to your query. If you use multiple queries in a Lumira application, it is enough to add it to one of them – the most important one. One which is initialized already on startup, and stays initialized during the whole lifecycle of the Lumira application. (Or else you could read the system ID during startup and store it in a global variable.)
If you don’t want the variable to disturb the result of your query, put it as in the title of a hidden dummy formula element created specifically for this purpose.
To find out which system we are on, create a method SCRIPT.getSystem() – returning string:
var sysId = DS_READ_USER_USERGRUPPE.getVariableValueExt("TCTSYSIDT001");
if (sysId == "ESD") {
return "dev";
} else if (sysId == "ESP") {
return "prod";
} else {
return "";
}
For easy maintenance, it would also make sense not to scatter your host names throughout the whole application but put them in separate methods like SCRIPT.getServerABAP().
var system = SCRIPT.getSystem();
if (system == "dev") {
return "abc.evosight.com";
} else if (system == "prod") {
return "xyz.evosight.com";
} else {
return "";
}
And finally, an example how to use this for opening maintenance of info object master data: SCRIPT.openInfoObjectMaintenance( infoObject ):
var url = "https://<server>/sap/bc/webdynpro/sap/rsdmdm_md_maintenance_app?IOBJNM=<infoObject>&IGNORE_READER_CLASS=X";
url = Convert.replaceAll(url, "<server>", SCRIPT.getServerABAP());
url = Convert.replaceAll(url, "<infoObject>", infoObject);
APPLICATION.openNewWindow(url);
The bookmark approach
While discussing with other consultants whether they have any other ideas for solving the issue, one came up with the idea of using bookmarks to identify the system. You would use the bookmarks component to check if a bookmark with a specific ID would exist or not. You do create such a bookmark on the development system, but it is never transported to the productive system. If the bookmark is found, you know you are on development, if not found, you are on productive. The approach is not too convenient (special temporary code required to create the bookmark), and also not too secure (someone might delete the bookmark by mistake) either.
You could by the way play the same game with the comments component.
Someone also suggested using the .geturl( id ) method of the bookmarks component for getting a URL – which is always system-dependent. This is more secure than the ‘does bookmark exist?’ method, but you need to create a dummy-bookmark on all systems, as the method will only work if a valid bookmark id has been passed.
All in all, the exit-variable based solution seems more robust, and you only need to implement it once – whereas bookmarks mean a per-app effort.