Wednesday 6 March 2024

Can I extend a certain app? With Clean Core? How?

Extensibility is a very important part in SAP S/4HANA. Although we recommend to have a fit-to-Standard approach, we know that not everything can be covered; there is a need for extensibility. But we don't just want to go hack about our system (anymore), we want to do it Clean Core compliant, meaning:

  • Extensions are clearly separated from SAP's code
  • Extensions do not modify any SAP objects
  • Extensions use only stable, released SAP APIs and extension points

But how to go about that? Well, I'm hoping to give some help on that. In this blog post I'm focusing on extending an SAP S/4HANA Standard app, as an example.

First of...


I want to start by saying that the below "guide" isn't exactly a guide, but rather a collection of ideas. I want to be fully honest and say that there are tons of ways to do an extension, and depending on your exact situation, one may be favored over another. So, do not see this as "the only way", but "a way" that could help you solve your extension need.

Please also note, as mentioned before, we are focusing on an extension for an existing standard app. Some extensions may include data from other systems than your S/4HANA and maybe are viable for side-by-side development (development in SAP BTP) using SAP Build, BAS, Integration Suite and/or other services. I will not touch on those scenarios in this blog, but we focus on extending directly in your S/4HANA system.

I found an app and I want to extend it - can I?


This is often the very first question that reaches me; can I extend app Fxxxx? The simple truth is, there isn't a super simple answer. There are several ways to go about checking if your app can be extended, here are some:

Part 1: Check Key User Extensibility

Make sure your user as the required roles for key user extensibility (SAP_UI_FLEX_KEY_USER for being able to adapt the UI and SAP_BR_EXTENSIBILITY_SPEC for being able to use extensibility apps such as Custom Fields and Custom Logic).

Open the app and the screen you wish to extend. In your user menu, select Adapt UI:

Can I extend a certain app? With Clean Core? How?

If this option is available, the app probably can be extended with Key User Extensibility (apps still can react differently on different UI sections and fields, and you simply need to try and see what’s possible when the mode is activated). If this option is not available, we come to that further below.
Whether you want to add a new field or define new logic for your extension, right click onto an appropriate group, and press "+ Add: Field" (if this option is greyed out/disabled, new fields can’t be added for that group of data):

Can I extend a certain app? With Clean Core? How?

In the next dialog you will see a list of existing fields which are currently not on the screen.

Can I extend a certain app? With Clean Core? How?

To add a new custom field, you can click on the plus icon in the upper right corner -> this will take you to the Custom Fields app in a new tab in your browser. When opening the app this way, the app is prepared to only show the business context of the app you are trying to extend:

Can I extend a certain app? With Clean Core? How?

By clicking the plus icon in the upper right corner here, you can add your custom field (there are lots of guides on how to do this, I don't focus on that in this blog post).

If the option "+ Add: Field" was greyed out, you can still check whether you can add your own logic by opening the Custom Logic app (use the new version, not depreciated, if available in your system -> check the Fiori Apps Reference Library). Using Adapt UI first, gives the advantage of you giving you the corresponding business context, which you must otherwise select manually.

Clicking on Create in the Custom Logic app lists all extension points released for Key User extensibility. You can search by free text or via Business Context to see if you find an extension point that fulfills your requirement:

Can I extend a certain app? With Clean Core? How?

If you found what you need, create a new custom logic and write your code there (there are lots of guides on how to do this, I don't focus on that in this blog post).

If none of the extension points fit, you can continue to see if Developer Extensibility is possible...

Part 2: Check On-Stack Developer Extensibility

Go to the Fiori Apps Reference Library and find your app there, for example:

Can I extend a certain app? With Clean Core? How?

Make sure you are on the correct SAP S/4HANA release for your solution (blue box). Open Implementation Information tab and check all the yellow marked boxes:

- If the Application Type isn’t SAP Fiori, it could be more difficult or not possible to extend (especially for Web-Dynpro apps – GUI transactions can possibly be modified with SAP Screen Personas for simpler requests)

- Under Extensibility you may find a documentation for extending the app (an SAP Help page) and you may find the technical name of the frontend application (BSP containing SAPUI5 application), which can be used for Adaptation Projects in SAP BTP BAS.

- Under Configuration you can find the OData Service(s) of the app. These contain the data model and underlying business logic for the app. A developer can analyze the main OData Service (sometimes there are several listed, for example an extra service for handling attachments that has otherwise nothing to do with the main business context of the app) to see whether it is extensible.

In-Depth development objects analysis

Checking the Fiori apps reference library should have given you some idea if the app can be extended with developer extensibility. You now need a developer to check further. At this point, I want to mention once more that below steps are not the only way to do these checks, but a possibility.

At this point we assume that our requirement cannot be solved with Key User extensibility. So now we want to check if we can extend the underlying OData service of the app to achieve our need.

Usually I start by determining in which Programming Model the OData service of the app was created:

- Old Programming Model with a code-based OData service created in transaction SEGW
- ABAP RESTful Application Programming Model (RAP) / ABAP Cloud development model

If the name of the OData service in the Fiori apps reference library ends with _CDS, we have a RAP service that was generated from a CDS view. If not, let's find out how the service was created (remember that this analysis is usually done by a developer):

1. In SAP GUI, open transaction se16n and enter table /IWBEP/I_SBD_GA
2. Under TROBJ_NAME enter the name of the OData service
3. Under TROBJ_TYPE enter value IWSV for OData service
4. Hit Execute (F8)

Can I extend a certain app? With Clean Core? How?

If nothing is found, the OData service should have been made with RAP. If you find a record, you find the name of the SEGW project in the first column:

Can I extend a certain app? With Clean Core? How?

SEGW Project

If the previous step led you to an SEGW project, open the transaction SEGW and open the project as found in the previous step. Depending on how the data model was built, we have more or less opportunities for extensions, for example:

Can I extend a certain app? With Clean Core? How?

◉ Data Model -> Entity Types: these types were manually created (field by field) in SEGW without any underlying CDS view, meaning we cannot affect these data models without changing the SAP project, which we will not do in Clean Core!

◉ Data Resource Reference -> Exposures via SADL -> CDS Entity Exposures: if we have CDS entities listed here, we may have some extension possibilities. Continue to "Analyze RAP Objects" below.
Even if this step ended in only manual entity types, we still have the option to check if an Adaptation Project can do our requirement. More on those further below.

Analyze RAP Objects (CDS, Business Service etc.)

If either our whole OData service was made with RAP or we have some CDS entities that used by an older OData service, we may have some options for extensions.

In ABAP Development Tools for Eclipse (ADT), connect to your system.

Check OData Service

Use Ctrl + Shift + A to open any development object. Enter the name of the OData service, for example:

Can I extend a certain app? With Clean Core? How?

Open the object with the purple icon for Service Binding. In the Service Binding you can find the Service Definition and all Entities exposed via this OData Service:

Can I extend a certain app? With Clean Core? How?

In the lower part of the screen, you find a Properties tab. Here you can for example find the Development Package of the service, which can help to find further objects.

Let's start by opening the Service Definition we can see on the Service Binding. Sadly, it is currently not possible to navigate forward (F3) from the Service Binding to the Service Definition and it’s also not possible to copy the name of the Service Definition. Either retype it into Ctrl + Shift + A or add the package from properties to your Favorite Packages (remember that not all RAP objects will be in that exact package, but most probably the Service Definition that belongs to the Service Binding will be):

Can I extend a certain app? With Clean Core? How?

Opening the Service Definition will list all the CDS objects exposed:

Can I extend a certain app? With Clean Core? How?

Start by checking the Properties of the Service Definition, and under it, the tab API State:

Can I extend a certain app? With Clean Core? How?

Here we can see all the "contracts" the object has been released for. In the above example, there is no Contract C0 for extensions, meaning this Service Definition cannot be extended. Not all is lost yet; this simply means we cannot expose additional CDS on this Service Definition, but we can still check the exposed CDS, if we can extend those (since they are exposed, if we extend them the change is reflected in the OData service because the underlying model changed).

Check CDS entities

From the Service Definition, we can click on a row with a CDS name and use forward navigation (F3) to open it. Once it’s open, we can check the API State here:

Can I extend a certain app? With Clean Core? How?

In the above example we can see that the CDS can indeed be extended, but only by Key User Apps; Cloud Development is not enabled for this object. In this case, we are back to Part 1: using UI Adaptation, Custom Fields, Custom Logic etc. apps.

In the same way as shown above, you can check the API state of any SAP object, for example a CDS entity you found in a SEGW project.

Open the CDS directly with Ctrl + Shift + A and enter its name, then check API State under Properties.

What about behavior or logic of an app? If the OData service is built with RAP, we can check the Behavior Definition of a CDS entity, whether it can be extended or not. Copy the name of the CDS entity and use again Ctrl + Shift + A and enter the name to find the behavior definition for it (they should have the same name), for example:

Can I extend a certain app? With Clean Core? How?

The purple B icon is for Behavior Definition. Open it and check its API state as explained before.

Check Extension Points

If your OData service is not made with RAP, or the behavior cannot be extended, then you have to look for released extension points to add your own logic. We already quickly looked at the Custom Logic app: the extension points listed there are released for Key User Extensibility. There could be more extension points available, for Developer Extensibility (as we've seen in the above contract C0, an object can be released for Key User or for Development, or for both).

My recommendation is to always check Key User first. If it is not sufficient, we need to try and find an extension point that is. How can we do that? Again, several options.

Can I extend a certain app? With Clean Core? How?

Once you found your extension point, you can see its Release State when you click on it:

Can I extend a certain app? With Clean Core? How?

The other option is to directly check in ADT via the "Released Objects" tree (which you may need to add by customizing your ADT tree):

Can I extend a certain app? With Clean Core? How?

Part 3: It's still not enough - what now?

Once you’ve checked both Key User Extensibility and Developer Extensibility and are still not able to fulfill your requirement, you still have a couple of options:

1. Create your own app, reusing standard CDS as much as possible (but wrapping them inside custom namespace, for example ZR_SalesOrderTP for reusing R_SalesOrderTP or I_SalesOrder etc.)

1.1 Add your new fields and/or behavior to your custom CDS

1.2 If you need your own custom table, consider if using Custom Business Objects works for your case. If not, be sure to build the RAP object properly (Database table, Basic interface view, View entity, View projection, Behavior, Behavior projection). Remember that custom business objects can have automatic Change Document handling, as well as System Administrative Data (created at, by, changed at, by) handling out-of-the-box.

1.2.1 How do I find my Custom Business Object in ADT? Open your Custom Business Object in the app and refer to Name of Technical Service:

Can I extend a certain app? With Clean Core? How?

1.2.2 In ADT, use again Ctrl + Shift + A and enter the name, but discard the final _CDS:

Can I extend a certain app? With Clean Core? How?

2. Try to extend the app by using an Adaptation Project with SAP Business Application Studio on SAP BTP. Keep in mind that Adaption Projects are mostly used to modify the UI and actions on the UI. If this does not fulfill your need, you may need to go with option 1 or 3.

3. There is a third, hybrid option: one other feature of Adaption Projects is to add your own OData service or even replace the main OData service. If you prefer to keep the standard app instead of making your own (and making a new version for it via the Adaptation Project), you could try this option. You would create your own OData service with RAP and then create an Adaptation Project for the standard app, combining option 1 and 2:

Can I extend a certain app? With Clean Core? How?

No comments:

Post a Comment