https://raw.githubusercontent.com/ajmaradiaga/feeds/main/scmt/topics/ABAP-Cloud-blog-posts.xml SAP Community - ABAP Cloud 2026-04-12T11:00:00.562058+00:00 python-feedgen ABAP Cloud blog posts in SAP Community https://community.sap.com/t5/sap-learning-blog-posts/sap-s-most-popular-certification-gets-a-major-upgrade/ba-p/14341746 SAP’s Most Popular Certification Gets a Major Upgrade 2026-03-06T15:55:26.136000+01:00 arabella https://community.sap.com/t5/user/viewprofilepage/user-id/145342 <P>March is officially the month of ABAP. SAP’s most popular certification for back-end developers, <A href="https://learning.sap.com/certifications/sap-certified-associate-back-end-developer-abap-cloud?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank" rel="noopener noreferrer">the Back-End Developer ABAP Cloud</A>, is getting a major upgrade. At the same time, the <A href="https://community.sap.com/t5/abap-blog-posts/abap-developer-challenge-joule-for-developers-using-basic-trial/ba-p/14336191?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank">SAP Community developer challenge for ABAP</A> is going live, making this the perfect moment to sharpen your skills and validate your expertise.</P><P><STRONG>A Reimagined Certification Experience</STRONG></P><P>The ABAP Cloud certification exam has been redesigned. Moving beyond traditional question-based formats, the new exam introduces a performance-based, open-book experience.</P><P>Learners now work directly in authentic SAP systems, navigating AI-supported, real-world scenarios that reflect actual project work. The focus is no longer on memorization; it’s about demonstrating practical skills that matter on the job.</P><P><STRONG>What does it mean for you?</STRONG></P><P>If you’ve been preparing for certification through the <A href="https://learning.sap.com/products/business-technology-platform/development/abap?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank" rel="noopener noreferrer">SAP Learning site</A>, you’re already familiar with hands-on exercises and scenario-based tasks embedded in the learning journeys. The <A href="https://learning.sap.com/get-certified/reimagining-certification?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank" rel="noopener noreferrer">new exam format</A> simply extends that approach.</P><P>From the moment you begin your certification, the experience feels familiar because it mirrors how you’ve been learning all along.</P><P>Every practical exam, whether system-based or scenario-driven reflects the reality of SAP projects:</P><UL><LI>Timeboxed tasks performed in live SAP systems</LI><LI>Realistic customer and project scenarios</LI><LI>AI-supported simulations</LI><LI>Open-book access to resources such as SAP Help Portal, SAP Learning, SAP Community, and SAP Joule for Consultants (where applicable)</LI><LI>A clear emphasis on proving your ability to do the work</LI></UL><P>This shift represents something bigger: trust. Trust in learners who invest in building real skills and trust from employers who rely on SAP-certified professionals to deliver value from day one.</P><P><STRONG>How to get certified as Backend Developer for ABAP Cloud</STRONG></P><P>Earning your certification is a structured journey. Whether you are new to ABAP or looking to formalize years of experience, the following resources will help you build a strong foundation and deepen your expertise.</P><P><STRONG>Recommended Courses to Build and Deepen Your Skills</STRONG></P><P>Start with the fundamentals and progressively expand your knowledge:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="SAP Certified - Backend Developer - ABAP Cloud (Kurse).gif" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379839i4004F7EF799FC8B1/image-size/large?v=v2&amp;px=999" role="button" title="SAP Certified - Backend Developer - ABAP Cloud (Kurse).gif" alt="SAP Certified - Backend Developer - ABAP Cloud (Kurse).gif" /></span></P><UL><LI>Course: <A href="https://learning.sap.com/courses/basic-abap-programming?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank" rel="noopener noreferrer">Learning Basic ABAP Programming</A></LI><LI>Course: <A href="https://learning.sap.com/courses/deepening-your-abap-programming-knowledge?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank" rel="noopener noreferrer">Deepening Your ABAP Programming Knowledge</A></LI><LI>Course: <A href="https://learning.sap.com/courses/building-data-models-with-the-abap-dictionary-and-abap-core-data-services?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank" rel="noopener noreferrer">Building Data Models with the ABAP Dictionary and ABAP Core Data Services</A></LI><LI>Course: <A href="https://learning.sap.com/courses/practicing-clean-core-extensibility-for-sap-s-4hana-cloud?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank" rel="noopener noreferrer">Practicing Clean Core Extensibility for SAP S/4HANA Cloud</A></LI><LI>SAP Certification: <A href="https://learning.sap.com/certifications/sap-certified-associate-back-end-developer-abap-cloud?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank" rel="noopener noreferrer">Backend Developer - ABAP Cloud</A></LI></UL><P>Together, these courses prepare you not just to pass the exam but to succeed in real-world ABAP Cloud development. Learn more about the exam details in <A href="https://community.sap.com/t5/blog-posts-about-sap-websites/a-new-system-based-abap-certification-is-here-what-developers-need-to-know/ba-p/14339753?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank">this community blog</A> by <A href="https://community.sap.com/t5/user/viewprofilepage/user-id/14191" target="_blank">@JenniferHauck</A>.</P><P><STRONG>Connect Live with SAP Experts and Strengthen Your Exam Readiness</STRONG></P><P>Learning doesn’t have to be a solo experience. If you’re looking for direct interaction, practical tips, and expert guidance, join the upcoming live sessions available through your SAP Learning Hub subscription:</P><UL><LI><A href="https://learning.sap.com/live-sessions/getting-started-with-abap-cloud-development?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank" rel="noopener noreferrer">Getting Started with ABAP Cloud Development</A></LI><LI><A href="https://learning.sap.com/live-sessions/get-certified-sap-certified-associate-back-end-developer-abap-cloud?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank" rel="noopener noreferrer">Get Certified: SAP Certified – Back-End Developer ABAP Cloud</A></LI><LI><A href="https://learning.sap.com/live-sessions/stay-certified-back-end-developer-abap-cloud-1?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank" rel="noopener noreferrer">Stay Certified: Back-End Developer – ABAP Cloud</A></LI></UL><P>These sessions offer the opportunity to clarify questions, reinforce key concepts, and gain confidence before taking the exam.</P><P><STRONG>Join the ABAP Developer Community to Learn, Share, and Grow</STRONG></P><P>Certification is just one milestone in your journey. Continuous learning happens through collaboration.<BR />Visit the <A href="https://community.sap.com/t5/abap/gh-p/abap?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank">ABAP developer forum</A> here on the SAP Community to:</P><UL><LI>Read expert blogs</LI><LI>Ask technical questions</LI><LI>Share your own insights</LI><LI>Connect with developers worldwide</LI></UL><P>Being part of the community ensures you stay current and continue growing long after certification.</P><P><STRONG>Experience Hands-On Learning at SAP CodeJam Events Near You</STRONG></P><P>If you prefer immersive, in-person learning, don’t miss the <A href="https://community.sap.com/t5/sap-codejam/eb-p/codejam-events?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank">upcoming SAP CodeJam events</A>. These sessions are designed to provide practical, guided experience with real SAP technologies in a collaborative environment.</P><P>Upcoming sessions include:</P><UL><LI>April 7: <A href="https://community.sap.com/t5/sap-codejam/abap-ai-capabilities-in-sap-joule-for-developers-codejam-s%C3%A3o-paulo-brazil/ev-p/14322983?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank">ABAP AI: Capabilities in SAP Joule for Developers CodeJam</A> (São Paulo, Brazil)</LI><LI>April 8: <A href="https://community.sap.com/t5/sap-codejam/abap-ai-capabilities-in-sap-joule-for-developers-codejam-londrina-brazil/ev-p/14324622?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank">ABAP AI: Capabilities in SAP Joule for Developers CodeJam</A> (Londrina, Brazil)</LI><LI>April 23: <A href="https://community.sap.com/t5/sap-codejam/sap-codejam-abap-cloud-warsaw-poland/ev-p/14331237?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank">ABAP Cloud and the RESTful Application Programming Model</A> (Warsaw, Poland)</LI></UL><P>These events are an excellent opportunity to deepen your understanding, expand your network, and gain hands-on practice. Be sure to explore the <A href="https://community.sap.com/t5/sap-codejam/eb-p/codejam-events?source=text-Global-Sapcommunity-prdteng-BTP" target="_blank">full event calendar</A> regularly, as new sessions are added on an ongoing basis.</P><P><STRONG>Continue Your Learning with On-Demand Developer Content</STRONG></P><P>Can’t attend live? Explore past Devtoberfest sessions, Tech Bytes, SAP CodeTalks, and more on the official <A href="https://www.youtube.com/@sapdevs/search?query=ABAP" target="_blank" rel="noopener nofollow noreferrer">SAP Developers YouTube channel</A></P><P>On-demand content allows you to learn at your own pace while staying connected to the latest innovations in ABAP and SAP development.</P><P>March is the perfect time to invest in your ABAP Cloud journey. With a certification experience designed to reflect real project work, you’re not just passing an exam, you’re demonstrating that you’re ready to build, extend, and innovate in the SAP ecosystem.</P> 2026-03-06T15:55:26.136000+01:00 https://community.sap.com/t5/abap-blog-posts/week-2-use-joule-chat-to-create-abap-rap-application-and-explore-the/ba-p/14341378 Week 2 : Use Joule Chat to create ABAP RAP Application and explore the Explain feature 2026-03-09T05:30:00.054000+01:00 sheenamk https://community.sap.com/t5/user/viewprofilepage/user-id/142394 <P>Last week we had completed the system set up and also created a package with your community ID. We had also gone through the help document on&nbsp;<SPAN class="">SAP Joule for Developers, ABAP AI Capabilities.</SPAN></P><P><SPAN class="">Now let us dive into the world of ABAP AI by creating an application where Joule will guide you during each step.</SPAN></P><P><FONT size="4"><STRONG>Quick Links</STRONG></FONT></P><P><SPAN>Please use&nbsp;</SPAN><A href="https://community.sap.com/t5/abap-forum/questions-march-2026-developer-challenge-joule-for-developers-in-abap/m-p/14342754#M686" target="_self">this separate thread to ask your questions and discuss issues</A>.&nbsp;</P><P><STRONG><U>Task 1:</U></STRONG> <STRONG>Create a ABAP RAP application using 'OData UI Service from Scratch’ wizard</STRONG></P><P>It can be any application of your choice preferably non enterprise related to keep the challenge simple and more interesting. One field should be an amount field and another one a date field so that we can leverage J4D(Joule for Developers) to add some logic in the subsequent weeks. You should have 3 more fields which will be used to try out some of the J4D features.</P><P><FONT color="#FF0000">Note: It is recommended to create all the fields while creating the app itself to avoid any manual coding later.</FONT></P><P>Example:- You can create a book store application consisting of fields ID, Title, Author, Price, Published Date, Stock, Discounted Price, BookAge. Here the last 3 fields can be used to try out the Joule for Developers (J4D) features. You are free to choose any dataset and logic combinations.</P><OL><LI>Right click on the package ZAC_&lt;your community ID&gt; created and select <STRONG>‘Generate ABAP Repository Objects’</STRONG><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Generate ABAP Repository Objects’" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379604i9DC639C2F78B9340/image-size/large?v=v2&amp;px=999" role="button" title="Wizard.jpg" alt="Generate ABAP Repository Objects’" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Generate ABAP Repository Objects’</span></span></LI><LI>In the below popup that appears choose <STRONG>‘Odata UI Service from Scratch’ </STRONG>and click on ‘Next’ two times.<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Odata UI Service from Scratch" style="width: 695px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379606i76D28D77E14E0D69/image-size/large?v=v2&amp;px=999" role="button" title="Odata UI Service From Scratch.jpg" alt="Odata UI Service from Scratch" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Odata UI Service from Scratch</span></span></LI><LI>Click ‘Next’ again.<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Click Next" style="width: 696px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379607i0FF732D1BB63D85C/image-size/large?v=v2&amp;px=999" role="button" title="Odata UI Service From Scratch-Next.jpg" alt="Click Next" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Click Next</span></span></LI><LI>In the next screen make sure you get the <STRONG>Joule</STRONG> Help to the right of Wizard popup. Here in the section <STRONG>‘Ask Joule to update the fields’</STRONG> can provide your prompts to create the application you like by specifying the fields and other details. Hit enter.&nbsp;<FONT color="#FF0000">Note: It is better to create all objects ending with your &lt;community ID&gt; to avoid any naming conflicts. Try to specify this in the prompt.</FONT><FONT color="#FF0000"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Joule option in Wizard" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379608i8A0D4B5E8D24C233/image-size/large?v=v2&amp;px=999" role="button" title="Joule Option in Wizard.jpg" alt="Joule option in Wizard" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Joule option in Wizard</span></span>Note: Make sure to select the option -&nbsp; ‘<STRONG>Transactional with Draft</STRONG>’ highlighted in the above screenshot is selected to enable ‘Create’ option in the application getting created. For single entity sometimes it is set as ‘Without Draft’.</FONT></LI><LI>Joule will now propose the Entity and Fields based on your prompt. Please note that we still should verify whether the suggestions are accurate for our requirements. Here you can notice that sometimes Joule suggests to change the Service Configuration to ‘Transactional Without Draft’, we can handle this in next step.<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Joule Field Proposal" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379609i9EC29A74446D9424/image-size/large?v=v2&amp;px=999" role="button" title="Joule Field Proposal.jpg" alt="Joule Field Proposal" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Joule Field Proposal</span></span></LI><LI>Once you are satisfied click on ‘Accept’ and you can see that the ‘Artifact Suffix’ if specified and the ‘Project Name’ gets added as shown in the below screenshot.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Here remember to change the Service Configuration to <STRONG>‘Transactional with Draft’ </STRONG><SPAN>and click</SPAN><STRONG> ‘Next’.</STRONG><STRONG><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Joule Accept Proposal" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379610iD366F6B462B31D99/image-size/large?v=v2&amp;px=999" role="button" title="Joule Field Accept.jpg" alt="Joule Accept Proposal" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Joule Accept Proposal</span></span></STRONG></LI><LI>Joule lists the artifacts that will be created. Verify them again and click on ‘Next’ and then ‘Finish’ on the next screen.&nbsp;</LI><LI>Refresh the package and check all the artifacts have been created. Publish the Service Binding and preview the application.</LI><LI>The application will open and should have a ‘Create’ button. Here you can either create a data generator class and add some simple logic to fill data / Use the ‘Create’ option in the app to create some sample records. ( Please create 4-5 entries in any case ). You can also adjust the metadata if you like.<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Application Created" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379626i1F894A52F6DD0D8A/image-size/large?v=v2&amp;px=999" role="button" title="App Create.jpg" alt="Application Created" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Application Created</span></span></LI></OL><P>For more information:&nbsp;<A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/use-odata-ui-service-from-scratch-wizard?locale=en-US" target="_blank" rel="noopener noreferrer">https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/use-odata-ui-service-from-scratch-wizard?locale=en-US</A></P><P><STRONG><U>Task 2: </U>Add a simple logic in the CDS data definition</STRONG></P><OL><LI>Add some simple logic in the CDS data definition for example to provide 2% discount on actual Price and fill another field say ‘DiscountedPrice’ with the discounted value for all records in the database.<P><FONT color="#FF0000">Note: The logic and examples are mentioned just for your reference and to make the purpose of the challenge easy to understand. Please feel free to use your own logic and dataset.</FONT></P></LI><LI><P>Now that one of the fields&nbsp;was enhanced, you may need to recreate the draft table&nbsp;ending with&nbsp;<STRONG>_D### </STRONG>before launching the application again. If you do not face any issue you can skip this step.</P><P>To do that, go to the&nbsp;<STRONG>Project Explorer</STRONG>&nbsp;and open the behavior definition click on the icon as shown on the picture to follow the quick fix. Save and activate the draft table.</P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Recreate Draft Table" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/379630iFDCBE186074A54B7/image-size/large?v=v2&amp;px=999" role="button" title="Draft Table.jpg" alt="Recreate Draft Table" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Recreate Draft Table</span></span></LI></OL><P><STRONG><U>Task 3: </U>Use Joule-&gt;Explain capability to understand code</STRONG></P><P>Use ‘Explain’ capability of Joule to get detailed explanation of the code added.</P><P><FONT color="#FF0000">Hint: Please add few lines of code like a simple CASE statement in CDS data definition to test Explain feature.</FONT></P><P>You may also watch this <A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/video-tutorials-for-explain-feature?locale=en-US" target="_self" rel="noopener noreferrer">video</A>&nbsp;to know more about how to use <STRONG>Joule-&gt;Explain</STRONG> feature.</P><P>We will be back next week with another feature of Joule AI Capability. Stay Tuned!!</P><P>&nbsp;</P> 2026-03-09T05:30:00.054000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/data-integration-in-abap-cloud-data-consumption-using-external-entities/ba-p/14344647 Data Integration in ABAP Cloud: Data Consumption using External Entities 2026-03-09T10:28:13.544000+01:00 SafaBahoosh https://community.sap.com/t5/user/viewprofilepage/user-id/763514 <P>In the previous post, we discussed <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/data-integration-in-abap-cloud-data-exposure-using-sql-services/bc-p/14344593#M188905" target="_self"><STRONG>data exposure</STRONG> using SQL services.</A> In this post, we shift the focus to the <STRONG>data consumption</STRONG> scenario.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Picture1.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/381395i324788F99265C91B/image-size/large?v=v2&amp;px=999" role="button" title="Picture1.png" alt="Picture1.png" /></span></P><P>Imagine an ABAP Cloud system that needs to access data located elsewhere, perhaps in an SAP HANA Cloud database, or even in another ABAP system. With SQL Services, an ABAP system can itself act as a database. To support such outbound data access in a clean and cloud-compliant way, ABAP Cloud introduces a new CDS modelling artifact: <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/abap-cds-release-news-2408-external-entities/ba-p/13784415" target="_blank"><STRONG>CDS External Entities</STRONG></A>.</P><P>&nbsp;</P><H2 id="toc-hId-1791432745"><STRONG>What Are CDS External Entities?</STRONG></H2><P>CDS External Entities enable outbound SQL access from an ABAP Cloud system. This means you can:</P><UL><LI>Access data from a remote database</LI><LI>Load and process remote data in ABAP</LI><LI>Combine remote data with local data</LI></UL><P>In ABAP Cloud, classic secondary database connections are not available. CDS External Entities are their more powerful and cloud-ready replacement.</P><P>Conceptually, a CDS External Entity is comparable to an SAP HANA virtual table; it represents a local view of a remote table or view. The remote object and its fields may have different names, which can be mapped explicitly.</P><P>CDS External Entities can be consumed in two different ways:</P><P><STRONG>- Dynamic Access</STRONG></P><P>In the SAP BTP ABAP environment, a CDS External Entity can be used directly in ABAP SQL. You write a SELECT statement that accesses data from a remote database, loads it, and processes it in ABAP.</P><P><STRONG>- Static Access </STRONG></P><P>Starting with release 2508, CDS view entities and classic CDS views can be built on top of external entities. This allows you to integrate remote data seamlessly into your CDS view modelling and treat it like local data. This feature will be used in my next blog post of the series.</P><H3 id="toc-hId-1724001959"><STRONG>Logical External Schema</STRONG></H3><P>Alongside CDS External Entities, there is a second important artifact: the Logical External Schema which is based on SAP HANA Smart Data Access (SDA). The key features are as follows:</P><UL><LI>It represents a remote system at design time.</LI><LI>It is mapped to a concrete remote source at configuration time.</LI><LI>It contains connection-related information (host, port, user, etc.).</LI></UL><P>From a runtime perspective, the ABAP system sends the query to its own HANA database, which then federates the query to the remote system using SDA.</P><P>&nbsp;</P><H2 id="toc-hId-1398405735"><STRONG>How External Entities Work at Runtime</STRONG></H2><P>External entities allow remote data access using a new ABAP SQL syntax:</P><P><EM>SELECT FROM &lt;external_entity&gt;</EM></P><P><EM>&nbsp; PROVIDED BY &lt;logical_external_schema&gt;</EM></P><P><EM>&nbsp; INTO TABLE <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1407137">@DATA</a>(result).</EM></P><P>In this flow:</P><OL><LI>The ABAP application sends the SQL query to the local HANA database.</LI><LI>HANA performs query federation using Smart Data Access.</LI><LI>Data is retrieved from the remote database.</LI><LI>Results are returned to the ABAP application server.</LI></OL><P>The &lt;logical_external_schema&gt; is a design-time artifact that points to the remote system and is bound to an actual remote source during configuration.</P><P>&nbsp;</P><H2 id="toc-hId-1201892230"><STRONG>Example Scenario</STRONG></H2><P>Let us build an example based on the travel scenario in which</P><UL><LI>SAP HANA Cloud acts as the remote database.</LI><LI>The ABAP system consumes data via Dynamic CDS External Entities.</LI></UL><P>It is crucial that</P><UL><LI>The external entity has the same name and field structure as the remote HANA table.</LI><LI>Field names and types must match <STRONG>exactly </STRONG>(HANA is case-sensitive).</LI></UL><P>Besides, to enable the access, an outbound service and a communication scenario are required.</P><H3 id="toc-hId-1134461444"><STRONG>Design Time Steps</STRONG></H3><P>1. Define a Dynamic CDS External Entity</P><pre class="lia-code-sample language-abap"><code>@AccessControl.authorizationCheck: #CHECK @EndUserText.label: 'external entity for travel' define external entity ZI_EE_TRAVEL_000 external name TRAVEL { key TravelID : abap.numc(8) external name "TravelID"; AgencyID : abap.numc(6) external name AgencyID; CustomerID : abap.numc(6) external name CustomerID; @Semantics.amount.currencyCode: 'CurrencyCode' BookingFee : abap.curr(16,2) external name BookingFee; @Semantics.amount.currencyCode: 'CurrencyCode' TotalPrice : abap.curr(16,2) external name TotalPrice; CurrencyCode : abap.cuky external name CurrencyCode; BeginDate : abap.dats external name BeginDate; EndDate : abap.dats external name EndDate; Description : abap.sstring(1024) external name Description; OverallStatus : abap.char(1) external name OverallStatus; CreatedBy : abp_creation_user external name CreatedBy; CreatedAt : abp_creation_tstmpl external name CreatedAt; LastChangedBy : abp_locinst_lastchange_user external name LastChangedBy; } with federated data provided at runtime;</code></pre><P>This entity models the structure of the remote table or view.</P><P>2. Define a Logical External Schema</P><P>This acts as a placeholder for the remote database and is referenced by the external entity.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="steampunk_external_schema_01_010.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/381385i8F40D96F6AD80167/image-size/large?v=v2&amp;px=999" role="button" title="steampunk_external_schema_01_010.png" alt="steampunk_external_schema_01_010.png" /></span></P><P>3. Create Outbound Service and Communication Scenario</P><UL><LI>Create an SQL type outbound service for the logical external schema<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="steampunk_outbound_service_02_010.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/381386i846C02436EE91851/image-size/large?v=v2&amp;px=999" role="button" title="steampunk_outbound_service_02_010.png" alt="steampunk_outbound_service_02_010.png" /></span></LI><LI>Create a communication scenario and assign the outbound service to it. Then save and publish the scenario locally.</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="scnario.png" style="width: 899px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/381389i88CF0AF2F1EC3836/image-size/large?v=v2&amp;px=999" role="button" title="scnario.png" alt="scnario.png" /></span></P><P>This enables administrators to configure access to the remote system</P><P>4. Consume the External Entity in ABAP SQL</P><P>Create a class and write ABAP SQL code</P><P><EM>Select * from <FONT color="#FF0000">my external entity</FONT> provided by <FONT color="#FF0000">my remote</FONT> into table <FONT color="#FF0000">my local table</FONT></EM></P><pre class="lia-code-sample language-abap"><code>CLASS zcl_travel_consume_000 DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES if_oo_adt_classrun . PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zcl_travel_consume_000 IMPLEMENTATION. METHOD if_oo_adt_classrun~main. data: travel type table of zi_ee_travel_000. select * from zi_ee_travel_000 provided by z_travel_remote_db_000 into table <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1428153">@Travel</a>. out-&gt;write( travel ). endmethod. ENDCLASS.</code></pre><P>In summary, what happens at runtime is as follows</P><UL><LI>The ABAP system sends the query to its HANA database</LI><LI>HANA SDA forwards the query to the remote database</LI><LI>Data is fetched and returned to the ABAP application</LI><LI>The local internal table is filled with remote data</LI></UL><P>Now we need to establish the connection between our development system and the SAP HANA Cloud database.</P><H3 id="toc-hId-937947939">&nbsp;</H3><H3 id="toc-hId-741434434"><STRONG>Configuration Time Steps</STRONG></H3><P>1. Create Communication Arrangement</P><P>In the SAP Fiori Launchpad:</P><UL><LI>Create a communication arrangement for the communication scenario you published in design time.</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="arrg1.png" style="width: 953px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/381390iF5EE6F2DFB5F28F1/image-size/large?v=v2&amp;px=999" role="button" title="arrg1.png" alt="arrg1.png" /></span></P><P>2.&nbsp;Maintain a communication system for the remote database</P><UL><LI>Activate Remote SQL-Access</LI><LI>Choose HANA ODBC as the SDA adapter</LI><LI>Provide host, port, driver, and additional connection settings<BR />(These details are typically provided by the system administrator)</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="sys.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/381391i1CFF2BDCF08917F7/image-size/large?v=v2&amp;px=999" role="button" title="sys.png" alt="sys.png" /></span></P><P>save the communication system.</P><P>3. Maintain Remote Schema Information</P><P>In the communication arrangement:</P><UL><LI>Specify the schema name of the remote HANA database</LI><LI>Save the configuration and check whether the connection is successful</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="arrg2.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/381392i007B52CB7607B7AE/image-size/large?v=v2&amp;px=999" role="button" title="arrg2.png" alt="arrg2.png" /></span></P><P>4.&nbsp;Prepare the Remote HANA Database</P><P>In Visual Studio Code and using SAP HANA Database Explorer:</P><UL><LI>Create a table that matches the CDS External Entity exactly</LI><LI>Ensure field names, types, and sizes match as well</LI></UL><P>Remember that SAP HANA is case-sensitive.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Remote-HANA .png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/381393i39A01E5CB6FE74EC/image-size/large?v=v2&amp;px=999" role="button" title="Remote-HANA .png" alt="Remote-HANA .png" /></span></P><H2 id="toc-hId-415838210"><STRONG>What Happens Behind the Scenes</STRONG></H2><P>When you execute the ABAP SQL statement:</P><UL><LI>The ABAP SQL layer resolves the external entity and logical external schema</LI><LI>HANA automatically:</LI><UL><LI>Creates a remote source</LI><LI>Creates the required virtual table</LI></UL><LI>Query federation is handled transparently</LI></UL><P>In this sense, CDS External Entities act as a smart abstraction that automatically manages HANA remote sources and virtual tables via ABAP design-time objects.</P><P>Press F9, and the data is returned as expected.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="data-in-pmd.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/381394i2E572DEAC030B0B7/image-size/large?v=v2&amp;px=999" role="button" title="data-in-pmd.png" alt="data-in-pmd.png" /></span></P><P>In the next blog post I would like to build a RAP application in the cloud, based on data I read from an on-premises system. So, stay tuned!</P> 2026-03-09T10:28:13.544000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/build-partner-add-on-with-ide-action/ba-p/14346989 Build Partner Add-on with IDE Action 2026-03-12T09:36:28.552000+01:00 birupakshya_sahu https://community.sap.com/t5/user/viewprofilepage/user-id/347289 <P><SPAN><STRONG>Disclaimer:</STRONG> The namespace&nbsp;</SPAN><SPAN>/ITAPC3/</SPAN><SPAN>&nbsp;is used throughout this document as an example namespace only. Replace it with your own namespace in real implementations.&nbsp;The coding style/naming conventions used in this blog are not recommendations on&nbsp;naming/design</SPAN><SPAN>&nbsp;<BR /></SPAN><SPAN>&nbsp;</SPAN><SPAN>&nbsp;<BR /></SPAN><SPAN>This blog post covers a step-by-step guide to how partners implement IDE Actions as Partner Add-ons in the&nbsp;SAP BTP ABAP Environment.&nbsp;This&nbsp;enables SAP partners to deliver customized tools in the form of custom action in ABAP Development Tools that increase developer&nbsp;productivity. By combining IDE Actions with the installable add-on&nbsp;option&nbsp;of the BTP ABAP Environment, partners have a potentially monetizable&nbsp;option&nbsp;to extend the ABAP Developer tools. It covers the key concepts and technologies –&nbsp;</SPAN><SPAN>how to extend ABAP Development Tools with IDE Actions and how to&nbsp;leverage&nbsp;the SAP Business Technology Platform ABAP Environment alongside the Landscape Portal to deliver installable add-on products.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Here we will look into a partner persona, where they&nbsp;can&nbsp;provide the business solution to their consumer with an&nbsp;installable&nbsp;add-on&nbsp;by providing certain action in the&nbsp;ABAP development tools, and also look into the consumer side of how they can consume the solution which caters to the needs of&nbsp;their&nbsp;developer using ABAP development tools (ADT).</SPAN><SPAN>&nbsp;</SPAN></P><H1 id="toc-hId-1662412617"><STRONG>Why&nbsp;IDE actions and Installable add-ons?&nbsp;</STRONG></H1><P><SPAN>By combining IDE actions and installable add-ons, partners who have been extending software can now also extend the ABAP Development Tools (ADT).</SPAN><SPAN>&nbsp;</SPAN></P><UL><LI><SPAN>The </SPAN><STRONG><SPAN>IDE action</SPAN></STRONG><SPAN> framework&nbsp;allows&nbsp;extending the ABAP development tools (ADT) with custom server-driven context-aware actions.&nbsp;</SPAN><SPAN>IDE Actions allow partners to automate repetitive tasks, such as creating specialized development objects, enhancing code analysis, or&nbsp;automating some code generation&nbsp;within ABAP Development Tools (ADT) for Eclipse.&nbsp;The implementation is&nbsp;completely server-driven using ABAP only.</SPAN><SPAN>&nbsp;</SPAN><SPAN>You can also use these custom functionalities&nbsp;with&nbsp;AI integration&nbsp;and&nbsp;XCO libraries.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><STRONG><SPAN>Installable add-ons&nbsp;</SPAN></STRONG><SPAN>are a set of software components bundled together as an add-on by a partner with the intent&nbsp;of providing&nbsp;a solution&nbsp;to their customers.&nbsp;</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>The </SPAN><STRONG><SPAN>Landscape Portal</SPAN></STRONG><SPAN> acts as a central tool to allow service providers to perform administration tasks such as hibernating systems, creating test tenants and support users, selecting systems for a pre-upgrade, but also lifecycle management operations such as building, deploying and updating product versions, and even guides you through the configuration and deployment of multitenant SaaS solutions.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><H2 id="toc-hId-1594981831"><STRONG>&nbsp;Business scenario:&nbsp;</STRONG></H2><P><SPAN>The developer can document&nbsp;development objects in the Knowledge Transfer Document Editor using Markdown syntax. Here partner is offering a translation&nbsp;</SPAN><SPAN>action with&nbsp;the help of IDE Action as Add-on for the Knowledge Transfer Document and can use the ABAP AI SDK powered by Intelligent Scenario Lifecycle Management (ISLM) to translate the Markdown syntax and display the output of translated Knowledge Transfer Document.&nbsp;Consume</SPAN><SPAN>r&nbsp;(The partner's customer)&nbsp;</SPAN><SPAN>can consume this solution from the partner through&nbsp;landscape portal as&nbsp;</SPAN><SPAN>Installable</SPAN><SPAN>&nbsp;</SPAN><SPAN>add-on and can use customized action in&nbsp;ABAP Development Tools&nbsp;for their&nbsp;development scenario.</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_0-1773301718243.png" style="width: 736px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382432i22D199275484BF07/image-dimensions/736x351?v=v2" width="736" height="351" role="button" title="birupakshya_sahu_0-1773301718243.png" alt="birupakshya_sahu_0-1773301718243.png" /></span></P><H2 id="toc-hId-1398468326"><STRONG>Prerequisites:&nbsp;(Partner)&nbsp;</STRONG></H2><UL><LI><SPAN>You’ve&nbsp;purchased&nbsp;entitlements that are necessary for the account setup. See </SPAN><A href="https://help.sap.com/docs/BTP/65de2977205c403bbc107264b8eccf4b/3bf575a3dc5043f895f8bd411d2a86a1.html?locale=en-US&amp;version=Cloud#loio4338854e3133407abb47d3a281dbd1e1" target="_blank" rel="noopener noreferrer"><SPAN>Prepare</SPAN></A><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>You’ve&nbsp;registered a namespace at SAP, for example /NAMESPC/. See </SPAN><A href="https://help.sap.com/docs/sap-btp-abap-environment/landscape-portal/maintain-namespaces" target="_blank" rel="noopener noreferrer"><SPAN>Register a Namespace</SPAN></A><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>You’ve&nbsp;registered your add-on at SAP, for example /NAMESPC/PRODUCTX. See </SPAN><SPAN>Register a Product</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>You are subscribed to the Landscape Portal</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>You have a user with the Landscape Portal Admin role collection assigned</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Install ABAP development tools for Eclipse (ADT) on your computer. If you already have ADT, make sure&nbsp;it's&nbsp;updated to the latest version. For more information, see </SPAN><A href="https://developers.sap.com/tutorials/abap-install-adt..html" target="_blank" rel="noopener noreferrer"><SPAN>ABAP Development Tools</SPAN></A><SPAN>.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>You need to have access to an&nbsp;SAP BTP ABAP&nbsp;Environment&nbsp;Instance</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Business&nbsp;Catalog&nbsp;SAP_A4C_BC_DEV_AIA_PC&nbsp;required&nbsp;for creating and editing IDE actions</SPAN><SPAN>&nbsp;</SPAN></LI></UL><H2 id="toc-hId-1201954821"><STRONG>&nbsp;Prerequisites:&nbsp;(Consumer)</STRONG><SPAN>&nbsp;</SPAN></H2><UL><LI><SPAN>The Landscape Portal Application has been subscribed&nbsp;to&nbsp;and your user has the landscape portal admin role collection assigned</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Install ABAP development tools for Eclipse (ADT) on your computer. If you already have ADT, make sure&nbsp;it's&nbsp;updated to the latest version. For more information,&nbsp;see </SPAN><A href="https://developers.sap.com/tutorials/abap-install-adt..html" target="_blank" rel="noopener noreferrer"><SPAN>ABAP Development Tools</SPAN></A><SPAN>.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><H1 id="toc-hId-876358597"><STRONG>&nbsp;Steps to Implement as a Partner&nbsp;</STRONG></H1><H2 id="toc-hId-808927811"><STRONG>1. Create Software Components&nbsp;</STRONG></H2><UL><LI><SPAN>To open the&nbsp;"Manage Software Components"&nbsp;application, log in to your SAP BTP ABAP Environment Fiori Launchpad&nbsp;as an administrator and Search for "Manage Software Components" in the search bar.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>use the “Create” button in the “Manage Software Components” app to open the dialog and fill in the information. We enter the name of the software&nbsp;component&nbsp;and a description.&nbsp;In the namespace dropdown you can use your reserved&nbsp;namespace. (Disclaimer: /ITAPC3/ being an example namespace used in this blog)</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_1-1773301769790.png" style="width: 597px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382433i7351B472F441A4D2/image-dimensions/597x315?v=v2" width="597" height="315" role="button" title="birupakshya_sahu_1-1773301769790.png" alt="birupakshya_sahu_1-1773301769790.png" /></span></P><UL><LI><SPAN>You&nbsp;clone&nbsp;the software&nbsp;component&nbsp;into the development system. When cloning, the main branch is checked out for the system, a package is created in the system that has the same name as the software&nbsp;component&nbsp;and is also assigned to it. At the same time, you can also set&nbsp;how the clone of the repository behaves&nbsp;in the system (push/pull or just pull).</SPAN><SPAN>&nbsp;</SPAN></LI><LI><SPAN>The software&nbsp;component&nbsp;with the selected branch is now imported into your current system instance. The&nbsp;Clone&nbsp;button turns into a&nbsp;Pull&nbsp;button. From now on, you can use it to pull (remotely available) changes of your software&nbsp;component&nbsp;to your system. Now you can see package under the selected&nbsp;software&nbsp;component&nbsp;in your system.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><H2 id="toc-hId-612414306"><STRONG>2.&nbsp; Development (Intelligent Scenario)&nbsp;</STRONG></H2><P><SPAN>Here in this scenario, we would be&nbsp;using&nbsp;ABAP AI Capabilities is&nbsp;our IDE Action implementation class to translate the markdown content into the target language with the help of ABAP AI SDK powered by ISLM.&nbsp;To learn more about Developing AI Enabled Applications with ABAP AI SDK powered by ISLM, refer to the&nbsp;</SPAN><A href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/developing-ai-enabled-applications-with-abap-ai-sdk-powered-by-islm/ba-p/14252514" target="_blank"><SPAN>blog post</SPAN></A><SPAN>.</SPAN><SPAN>&nbsp;</SPAN></P><H3 id="toc-hId-544983520"><STRONG>2.1&nbsp;Create ISLM Scenario:&nbsp;</STRONG></H3><UL><LI><SPAN>Select your package, right-click, </SPAN><STRONG><SPAN>New → Other → Intelligent Scenario →&nbsp;/ITAPC3/ADT_INT_SCE</SPAN></STRONG><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_2-1773301823207.png" style="width: 650px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382435i298353F3A70F91DB/image-dimensions/650x455?v=v2" width="650" height="455" role="button" title="birupakshya_sahu_2-1773301823207.png" alt="birupakshya_sahu_2-1773301823207.png" /></span></P><P><SPAN>Enter a name and description. Select </SPAN><I><SPAN>SIDEBYSIDE </SPAN></I><SPAN>for </SPAN><STRONG><SPAN>Scenario Technology</SPAN></STRONG><SPAN> field. Choose </SPAN><STRONG><SPAN>Next&nbsp;and&nbsp;</SPAN></STRONG><SPAN>then</SPAN><STRONG><SPAN>&nbsp;</SPAN></STRONG><SPAN>click</SPAN><STRONG><SPAN>&nbsp;Finish.</SPAN></STRONG><SPAN>&nbsp;</SPAN></P><H3 id="toc-hId-348470015"><STRONG>2.2&nbsp;Create ISLM Model:&nbsp;</STRONG></H3><UL><LI><SPAN>Select your package, right-click, New → Other → Intelligent Scenario Model</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Fill the </SPAN><I><SPAN>Description </SPAN></I><SPAN>and </SPAN><I><SPAN>Model Name </SPAN></I><SPAN>fields. Assign the previously created scenario in </SPAN><I><SPAN>Intelligent Scenario Name.</SPAN></I><SPAN> Choose Next. </SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_3-1773301823208.png" style="width: 655px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382434i2C6F60DBC627630A/image-dimensions/655x412?v=v2" width="655" height="412" role="button" title="birupakshya_sahu_3-1773301823208.png" alt="birupakshya_sahu_3-1773301823208.png" /></span></P><UL><LI><SPAN>Enter the </SPAN><I><SPAN>ExecutableID </SPAN></I><SPAN>and </SPAN><I><SPAN>Large Language Model Name </SPAN></I><SPAN>and </SPAN><I><SPAN>Large Language Model Version&nbsp;and&nbsp;Activate the object.</SPAN></I><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_4-1773301823209.png" style="width: 656px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382436iAD11B9D6416C9E85/image-dimensions/656x425?v=v2" width="656" height="425" role="button" title="birupakshya_sahu_4-1773301823209.png" alt="birupakshya_sahu_4-1773301823209.png" /></span></P><H2 id="toc-hId-22873791"><STRONG>3.&nbsp; Development&nbsp;(IDE Action)&nbsp;</STRONG></H2><P><SPAN>In this&nbsp;section&nbsp;we will look at the IDE action&nbsp;which translates the markdown content into the&nbsp;selected&nbsp;language with the help of&nbsp;</SPAN><SPAN>intelligent</SPAN><SPAN>&nbsp;</SPAN><SPAN>scenario created in the&nbsp;previous&nbsp;step.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Partners can&nbsp;utilize&nbsp;the </SPAN><STRONG><SPAN>ABAP AI SDK</SPAN></STRONG><SPAN> powered by ISLM to embed Generative AI features in&nbsp;IDE action implementation class.</SPAN><SPAN>&nbsp;</SPAN></P><UL><LI><SPAN>From ABAP Development Tools,&nbsp;locate&nbsp;and add to the&nbsp;favorite&nbsp;package “/ITAPC3/IDE_ACTION_EXTENSIONS“ that&nbsp;was created during Create Software Components process.&nbsp;The package has the same name as the software&nbsp;component.</SPAN><SPAN>&nbsp;</SPAN></LI><LI><SPAN>Create a new IDE action either from the main menu, project explorer, or toolbar.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>In the main menu, choose&nbsp;File-&gt;New-&gt;Other... and select IDE Action. The creation wizard opens.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>In the creation wizard, enter the project and package details if they are not already filled. Also, provide a name and description for the IDE action.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Choose Next, assign a transport request if needed&nbsp;and&nbsp;Choose Finish.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_5-1773301823211.png" style="width: 625px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382438i4E8CCEC91894B0CE/image-dimensions/625x318?v=v2" width="625" height="318" role="button" title="birupakshya_sahu_5-1773301823211.png" alt="birupakshya_sahu_5-1773301823211.png" /></span></P><UL><LI><SPAN>After we have created the action in the system, we then fill the form with the relevant information to create the action and the&nbsp;Input UI Configuration Class.</SPAN><SPAN>&nbsp;</SPAN><SPAN>In the </SPAN><STRONG><SPAN>Filter: Cardinality</SPAN></STRONG><SPAN> section, decide the number of focused resources that can be selected when running an IDE action.</SPAN><SPAN>&nbsp;</SPAN><SPAN>If you want to use your IDE action for any object type, add </SPAN><STRONG><SPAN>*ALL</SPAN></STRONG><SPAN> as value for the object type.&nbsp;Save and activate your IDE action.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><SPAN>&nbsp;</SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_6-1773301823212.png" style="width: 659px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382437i56D6164914893AAC/image-dimensions/659x506?v=v2" width="659" height="506" role="button" title="birupakshya_sahu_6-1773301823212.png" alt="birupakshya_sahu_6-1773301823212.png" /></span></P><H3 id="toc-hId--119788364"><STRONG>3.1&nbsp;Defining&nbsp;UI&nbsp;</STRONG></H3><UL><LI><SPAN>In the first step we need an action dialog to enable the user to enter data. To do this we can create a new class using the link in the IDE Action. This implements the interface IF_AIA_SD_ACTION_INPUT, but only the method CREATE_INPUT_CONFIG is defined here; the other three methods can be implemented optionally. We define a public type in the class as the structure for the input; we can give the fields certain properties using the ABAP Docs. A list of properties&nbsp;</SPAN><SPAN>can be found in the documentation, with certain properties being set via configuration.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code>CLASS /itapc3/cl_trans_ui_info DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES if_aia_sd_action_input. "! &lt;p class="shorttext"&gt;Simple Controls&lt;/p&gt; BEGIN OF ty_input, "! &lt;p class="shorttext"&gt;Select the language&lt;/p&gt; custom_value_help_text_field TYPE string, "! &lt;p class="shorttext"&gt;Enter the markdown source for the translation&lt;/p&gt; multiline_text_field TYPE string, END OF ty_input. PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS /ITAPC3/CL_TRANS_UI_INFO IMPLEMENTATION. METHOD if_aia_sd_action_input~create_input_config. " Create the input data with default values DATA(input_data) = VALUE ty_input( ) ##NO_TEXT. " Create the configuration via the factory DATA(configuration) = ui_information_factory&gt;get_configuration_factory( )-&gt;create_for_data( input_data ). " Set the layout configuration-&gt;set_layout( if_sd_config_element=&gt;layout-grid ). " Set configuration for elements “To enable a custom value help for an element, the corresponding configuration must be set via the API: configuration-&gt;get_element( 'custom_value_help_text_field' )-&gt;set_values( if_sd_config_element=&gt;values_kind-domain_specific_named_items ). configuration-&gt;get_element( 'multiline_text_field' )-&gt;set_multiline( if_sd_config_element=&gt;height-large ). " Create and return the UI information result = ui_information_factory-&gt;for_abap_type( abap_type = input_data configuration = configuration ). ENDMETHOD. METHOD if_aia_sd_action_input~get_value_help_provider. " Return a reference to your value help handler via the value help provider result = cl_sd_value_help_provider=&gt;create( NEW /ITAPC3/CL_TRAN_VALUE_HELP( ) ). ENDMETHOD. ENDCLASS. </code></pre><P>&nbsp;</P><H3 id="toc-hId--316301869"><STRONG>3.2&nbsp;Implement a Custom Value Help:&nbsp;</STRONG></H3><UL><LI><SPAN>To implement a custom value help that returns domain-specific named items, a handler class must be provided that implements the if_sd_value_help_dsni interface. The get_value_help_items method returns the values for the value help. The values to be returned are of type if_sd_value_help_dsni=&gt;ty_named_item_list.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code>CLASS /itapc3/cl_trans_ide_action DEFINITION PUBLIC FINAL CREATE PUBLIC. PUBLIC SECTION. INTERFACES if_aia_action. PROTECTED SECTION. PRIVATE SECTION. METHODS get_input_as_html IMPORTING ui_input TYPE /itapc3/cl_trans_ui_info=&gt;ty_input RETURNING VALUE(result) TYPE string. ENDCLASS. CLASS /ITAPC3/CL_TRANS_IDE_ACTION IMPLEMENTATION. METHOD get_input_as_html. FINAL(nl) = cl_abap_char_utilities=&gt;newline. TRY. DATA(completion_api) = cl_aic_islm_compl_api_factory=&gt;get( )-&gt;create_instance( '/ITAPC3/ADT_INT_SCE' ). DATA(prompt) = |You are a translator. Reject Hate Speech. Translate the given text into { ui_input-custom_value_help_text_field }:{ nl }{ ui_input-multiline_text_field }| ##NO_TEXT. DATA(translation) = completion_api-&gt;execute_for_string( prompt )-&gt;get_completion( ). CATCH cx_aic_api_factory INTO DATA(aic_api_factory_ex). RETURN. CATCH cx_aic_completion_api INTO DATA(aic_completion_api_ex). RETURN. ENDTRY. result = '&lt;h3 style="color:gray"&gt;Translate to (' &amp;&amp; ui_input-custom_value_help_text_field &amp;&amp; ')&lt;/h3&gt;' &amp;&amp; nl &amp;&amp; '&lt;pre&gt;' &amp;&amp; translation &amp;&amp; '&lt;/pre&gt;'. ENDMETHOD. METHOD if_aia_action~run. DATA(focused_resource) = context-&gt;get_focused_resource( ). TRY. DATA ui_input TYPE /itapc3/cl_trans_ui_info=&gt;ty_input. context-&gt;get_input_config_content( )-&gt;get_as_structure( IMPORTING result = ui_input ). CATCH cx_sd_invalid_data INTO DATA(exception). CLEAR ui_input. ENDTRY. DATA(popup_result) = cl_aia_result_factory=&gt;create_html_popup_result( ). popup_result-&gt;set_content( get_input_as_html( ui_input ) ). result = popup_result. ENDMETHOD. ENDCLASS. </code></pre><P>&nbsp;</P><P><SPAN>To start the action in Eclipse,&nbsp;we can&nbsp;copy the markdown source from any KTD Editor&nbsp;and use &nbsp;use&nbsp;the shortcut&nbsp;Ctrl&nbsp;+&nbsp;Alt&nbsp;+&nbsp;R&nbsp;for Windows or&nbsp;CMD&nbsp;+&nbsp;OPT&nbsp;+&nbsp;R&nbsp;for Mac or choose&nbsp;Run-&gt;ABAP IDE Action...&nbsp;from the main menu to start the Action Dialog, where our IDE Action should now be available.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Once all the required objects are created&nbsp;and the action is working as per our expectation, we&nbsp;have to&nbsp;release the Transport Request.</SPAN><SPAN>&nbsp;</SPAN></P><H2 id="toc-hId--219412367"><STRONG>4.&nbsp; Create&nbsp;Add-on Product using Landscape Portal&nbsp;</STRONG></H2><P><SPAN>The </SPAN><STRONG><SPAN>Landscape Portal</SPAN></STRONG><SPAN> acts as a central tool to allow service providers to perform administration tasks such as hibernating systems, creating test tenants and support users, selecting systems for a pre-upgrade, but also lifecycle management operations such as building, deploying and updating product versions, and even guides you through the configuration and deployment of multitenant SaaS solutions.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Here partner can create a&nbsp;new&nbsp;Add-on&nbsp;product,&nbsp;register your product,&nbsp;build a product version via&nbsp;pipelines&nbsp;and&nbsp;deploy a product version.</SPAN><SPAN>&nbsp;</SPAN></P><H3 id="toc-hId--709328879"><STRONG>4.1&nbsp;Register Product&nbsp;</STRONG></H3><P><SPAN>A product refers to an ABAP add-on that can be installed on SAP BTP, ABAP environment.</SPAN><SPAN>&nbsp;</SPAN></P><UL><LI><SPAN>Log into the </SPAN><STRONG><SPAN>Landscape Portal</SPAN></STRONG><SPAN>.</SPAN><SPAN>&nbsp;For more information, see&nbsp;</SPAN><A href="https://help.sap.com/docs/sap-btp-abap-environment/landscape-portal/accessing-landscape-portal" target="_blank" rel="noopener noreferrer"><STRONG><SPAN>Landscape Portal</SPAN></STRONG></A><SPAN>&nbsp;</SPAN><SPAN>&nbsp;</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Click on the </SPAN><STRONG><SPAN>Register Product</SPAN></STRONG><SPAN> tile to open the app.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>A list of all your created products, including their product ID, namespace and registration status, is displayed. The registration status&nbsp;indicates&nbsp;whether a product has already been registered to the global account you are currently logged in to.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Click the </SPAN><STRONG><SPAN>Create</SPAN></STRONG><SPAN> button in the top right corner.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Enter the name of the product you want to create and confirm with </SPAN><STRONG><SPAN>Create</SPAN></STRONG><SPAN>. Your request for creation has been sent and the registration status of the product changes to “Pending…”.&nbsp;The namespace is automatically&nbsp;determined&nbsp;from the product name you entered, and the product ID is generated as part of the creation process.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_7-1773302190960.png" style="width: 673px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382439iBB3E8BB1AC1CA9DB/image-dimensions/673x259?v=v2" width="673" height="259" role="button" title="birupakshya_sahu_7-1773302190960.png" alt="birupakshya_sahu_7-1773302190960.png" /></span></P><H3 id="toc-hId--905842384"><SPAN>&nbsp;</SPAN><STRONG>4.2&nbsp;Build Product Version&nbsp;</STRONG></H3><P><SPAN>You can use the </SPAN><STRONG><SPAN>Build Product Version</SPAN></STRONG><SPAN> app to easily trigger the build of new product versions via pipelines based on templates that you can configure for different use cases such as new (test or production) release deliveries, (test or production) support packages or (test or production) hotfixes/patch deliveries.</SPAN><SPAN>&nbsp;</SPAN></P><UL><LI><SPAN>Log in to the </SPAN><STRONG><SPAN>Landscape Portal</SPAN></STRONG><SPAN> and click on the tile </SPAN><STRONG><SPAN>Build Product Version</SPAN></STRONG><SPAN>.&nbsp;</SPAN><SPAN>For more information, see&nbsp;</SPAN><A href="https://help.sap.com/docs/sap-btp-abap-environment/landscape-portal/create-new-product-version" target="_blank" rel="noopener noreferrer"><STRONG><SPAN>Build Product Version</SPAN></STRONG></A><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Select one of your products from the list. You will be&nbsp;forwarded&nbsp;to the </SPAN><STRONG><SPAN>Product Versions</SPAN></STRONG><SPAN> tab. Here, you can see a table listing all the existing versions of this product, their type, when they were created, as well as their delivery status.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>You also need to Configure a Pipeline Template&nbsp;for release build.&nbsp;</SPAN><SPAN>For more information, see&nbsp;</SPAN><A href="https://help.sap.com/docs/sap-btp-abap-environment/landscape-portal/configure-pipeline-template" target="_blank" rel="noopener noreferrer"><SPAN>Configure a Pipeline Template</SPAN></A><SPAN>&nbsp;and&nbsp;</SPAN><A href="https://developers.sap.com/tutorials/abap-environment-saas-addon-build..html#2d3f1efd-4231-4f6e-a418-e3015d8a9d95" target="_blank" rel="noopener noreferrer"><SPAN>Create a template for release build.</SPAN></A><SPAN>&nbsp;</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>To create a new product version, click the </SPAN><STRONG><SPAN>Create</SPAN></STRONG><SPAN> button, choose </SPAN><STRONG><SPAN>Release</SPAN></STRONG><SPAN>&nbsp;</SPAN><STRONG><SPAN>Delivery</SPAN></STRONG><SPAN> and select the desired type. The resulting product version will be calculated automatically.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Select software components to be included in your new product version. To add&nbsp;additional&nbsp;software components, click the </SPAN><STRONG><SPAN>Add</SPAN></STRONG><SPAN> button on the right. For each software&nbsp;component, define a&nbsp;component&nbsp;version, enter the desired&nbsp;branch&nbsp;and commit ID as seen in the </SPAN><STRONG><SPAN>Manage Software Components</SPAN></STRONG><SPAN> app, and select in which languages your product version should be built. To get relevant&nbsp;commit ID&nbsp;for the software&nbsp;component&nbsp;involved in the build, you can refer&nbsp;the&nbsp;</SPAN><A href="https://help.sap.com/docs/btp/sap-business-technology-platform/how-to-display-commits-and-commit-objects?version=Cloud" target="_blank" rel="noopener noreferrer"><SPAN>help page</SPAN></A><SPAN>&nbsp;to get more details on this.</SPAN><SPAN>&nbsp;</SPAN><SPAN>Identify&nbsp;the commit based on which you wish to build your add-on product.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_8-1773302190961.png" style="width: 674px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382441iFC50C68FF5C2E575/image-dimensions/674x301?v=v2" width="674" height="301" role="button" title="birupakshya_sahu_8-1773302190961.png" alt="birupakshya_sahu_8-1773302190961.png" /></span></P><UL><LI><SPAN>Click the </SPAN><STRONG><SPAN>Build Product Version</SPAN></STRONG><SPAN> button to trigger the build of the pipeline for your new product version.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>You will be redirected to the Pipeline Status screen, where you can track the progress of your build.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_9-1773302190962.png" style="width: 670px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382440iE484999CFC8DC66E/image-dimensions/670x241?v=v2" width="670" height="241" role="button" title="birupakshya_sahu_9-1773302190962.png" alt="birupakshya_sahu_9-1773302190962.png" /></span></P><H3 id="toc-hId--1102355889"><STRONG>4.3&nbsp;Check Product Version&nbsp;</STRONG></H3><P><SPAN>The </SPAN><STRONG><SPAN>Check Product Version</SPAN></STRONG><SPAN> app lets you view the results of product version delivery infrastructure checks to see if your product version is ready for delivery. </SPAN><SPAN>&nbsp;</SPAN></P><UL><LI><SPAN>Click on the </SPAN><STRONG><SPAN>Check Product Version</SPAN></STRONG><SPAN> tile to open the&nbsp;app.&nbsp;</SPAN><SPAN>For&nbsp;more information, see&nbsp;</SPAN><A href="https://help.sap.com/docs/LANDSCAPEPORTAL_S4ABAP/bbef3473740144d38c8485d26871a1f0/4de24e56f52d4ca4ae8971aae6861f8e.html" target="_blank" rel="noopener noreferrer"><STRONG><SPAN>Check Product Version</SPAN></STRONG></A><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>A list of all your products is displayed. Select one of the products from the list.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Ready for production (P): The product version is ready for production use.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_10-1773302190963.png" style="width: 686px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382442i9815655FCE98E34F/image-dimensions/686x343?v=v2" width="686" height="343" role="button" title="birupakshya_sahu_10-1773302190963.png" alt="birupakshya_sahu_10-1773302190963.png" /></span></P><H3 id="toc-hId--1298869394"><STRONG>4.4&nbsp;Publish Product&nbsp;</STRONG></H3><P><SPAN>You, as a partner, have developed a product that you want to make available to your customers as an add-on that they can install into their system. You can use the Publish Product app to publish your product in a specific version for use&nbsp;by customers. Your customer can then use the </SPAN><A href="https://help.sap.com/docs/sap-btp-abap-environment/landscape-portal/discover-product?locale=en-US&amp;state=PRODUCTION&amp;version=Cloud" target="_blank" rel="noopener noreferrer"><SPAN>Discover Product</SPAN></A><SPAN> app to view all product versions that were published,&nbsp;i.e.&nbsp;made available, for them and can register a product, thus adding a product to their pool of product versions available for deployment.</SPAN><SPAN>&nbsp;</SPAN></P><OL><LI><SPAN>Log into the </SPAN><STRONG><SPAN>Landscape Portal</SPAN></STRONG><SPAN>.</SPAN><SPAN>&nbsp;</SPAN></LI></OL><OL><LI><SPAN>Click the </SPAN><STRONG><SPAN>Publish Product</SPAN></STRONG><SPAN> tile to open the app.&nbsp;</SPAN><SPAN>For more information, see&nbsp;</SPAN><A href="https://help.sap.com/docs/LANDSCAPEPORTAL_S4ABAP/bbef3473740144d38c8485d26871a1f0/900f8604d3ab41e38abfa990c68e429b.html" target="_blank" rel="noopener noreferrer"><STRONG><SPAN>Publish Product</SPAN></STRONG></A><SPAN>&nbsp;</SPAN></LI></OL><OL><LI><SPAN>Select the product from the list. You are&nbsp;forwarded&nbsp;to the configuration page. Click the </SPAN><STRONG><SPAN>Edit</SPAN></STRONG><SPAN> button.</SPAN><SPAN>&nbsp;</SPAN></LI></OL><OL><LI><SPAN>In the </SPAN><STRONG><SPAN>Product Configuration</SPAN></STRONG><SPAN> section, select the </SPAN><STRONG><SPAN>Product Version</SPAN></STRONG><SPAN> that you want to publish and choose </SPAN><STRONG><SPAN>SAP Store</SPAN></STRONG><SPAN> as the </SPAN><STRONG><SPAN>Distribution Channel</SPAN></STRONG><SPAN>.</SPAN><SPAN>&nbsp;</SPAN></LI></OL><OL><LI><SPAN>Click the </SPAN><STRONG><SPAN>Publish</SPAN></STRONG><SPAN> button to publish your product version</SPAN><SPAN>&nbsp;</SPAN></LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_11-1773302190963.png" style="width: 673px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382443iBEFCFE00211F76E1/image-dimensions/673x318?v=v2" width="673" height="318" role="button" title="birupakshya_sahu_11-1773302190963.png" alt="birupakshya_sahu_11-1773302190963.png" /></span><SPAN>&nbsp;</SPAN></P><H1 id="toc-hId--908576885"><STRONG>Steps&nbsp;performed from the&nbsp;Consumer&nbsp;</STRONG></H1><H2 id="toc-hId--1398493397"><STRONG>1. Discover Product&nbsp;</STRONG></H2><UL><LI><SPAN>Once Partner has made their product available and has published a product version using the Publish Product app, customers can register the product via&nbsp;</SPAN><A href="https://help.sap.com/docs/LANDSCAPEPORTAL_S4ABAP/bbef3473740144d38c8485d26871a1f0/724f5b6f69634f5ab7a8d6236f327e5a.html" target="_blank" rel="noopener noreferrer"><SPAN>Discover Product app</SPAN></A><SPAN>.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>After registrations customers&nbsp;can&nbsp;deploy the product using Deploy Product.&nbsp;</SPAN><SPAN>&nbsp;</SPAN></LI></UL><H2 id="toc-hId--1595006902"><STRONG>2.&nbsp; Deploy Product&nbsp;</STRONG></H2><P><SPAN>You can use the </SPAN><A href="https://help.sap.com/docs/LANDSCAPEPORTAL_S4ABAP/bbef3473740144d38c8485d26871a1f0/c4da7bba8b5a46b9ae08986d9399046d.html" target="_blank" rel="noopener noreferrer"><SPAN>Deploy Product</SPAN></A><SPAN> app to deploy or update your product version in specific systems.</SPAN><SPAN>&nbsp;</SPAN></P><UL><LI><SPAN>Sign in to the Landscape Portal.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Click on the Deploy Product tile to open the app.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>On the left side, under Product and Product Version Selection, select which product and version you want to deploy or update from the drop-down menu.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>In the Available Systems section, select at least one system in which you want to deploy or update the product version. You can also select multiple systems at once.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Click the Deploy button. A dialog box will open. Fill in the remaining details:</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Title: Choose a title for your update.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>From: Select the time the update can begin.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>To: The estimated time at which the product version update will be completed.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Confirm with Schedule.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Check the list under Product Version Update Status. Here, all update requests as well as their&nbsp;current status&nbsp;and progress are displayed. The update you just scheduled has been added to the list.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Once the product is deployed successfully then Customer can access the product in target system.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><SPAN>SAP BTP automatically&nbsp;activates the software&nbsp;component&nbsp;provided from the partner in the ABAP environment, makes packages visible&nbsp;and registers IDE extensions.</SPAN><SPAN>&nbsp;</SPAN></P><H2 id="toc-hId--1623336716"><STRONG>3.&nbsp; Test IDE Action&nbsp;</STRONG></H2><P><SPAN>Create/Use ABAP Cloud project in the ABAP instance where you have deployed the&nbsp;product.This&nbsp;should be a development system.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Open any&nbsp;Knowledge Transfer Document&nbsp;in the editor and copy the content.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>To open the </SPAN><STRONG><SPAN>Run ABAP IDE Action</SPAN></STRONG><SPAN> dialog, use the shortcut Ctrl + Alt + R for Windows or CMD + OPT + R for Mac or choose </SPAN><STRONG><SPAN>Run-&gt;ABAP IDE Action...</SPAN></STRONG><SPAN> from the main menu.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Select the IDE action&nbsp;“Translate markdown content”&nbsp;you would like to run Select </SPAN><STRONG><SPAN>Run</SPAN></STRONG><SPAN>.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>It will open&nbsp;the action input dialog&nbsp;where you can select the target language you want to translate and in next text box area provide the&nbsp;Knowledge Transfer Document&nbsp;content.</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_13-1773302190964.png" style="width: 673px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382445i5CFA0D01A2E06FD3/image-dimensions/673x471?v=v2" width="673" height="471" role="button" title="birupakshya_sahu_13-1773302190964.png" alt="birupakshya_sahu_13-1773302190964.png" /></span></P><P><SPAN>Select </SPAN><STRONG><SPAN>Run.</SPAN></STRONG><SPAN>&nbsp;</SPAN></P><P><SPAN>The result dialog for the selected IDE action opens the result dialog&nbsp;where it translates the&nbsp;Knowledge Transfer Document&nbsp;to the selected language&nbsp;option&nbsp;from the input dialog.</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="birupakshya_sahu_14-1773302190965.png" style="width: 677px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/382446i6E809A615D9DEDAC/image-dimensions/677x405?v=v2" width="677" height="405" role="button" title="birupakshya_sahu_14-1773302190965.png" alt="birupakshya_sahu_14-1773302190965.png" /></span></P><P>&nbsp;</P><P><SPAN>&nbsp;</SPAN></P> 2026-03-12T09:36:28.552000+01:00 https://community.sap.com/t5/abap-blog-posts/week-3-use-rap-business-logic-prediction-to-implement-validation/ba-p/14342759 Week 3 : Use RAP Business Logic Prediction to Implement Validation 2026-03-16T05:30:00.017000+01:00 sheenamk https://community.sap.com/t5/user/viewprofilepage/user-id/142394 <P>Last week we had created a RAP Application and added some entries in it. We also explored how to use Joule's 'Explain' feature to understand a simple code added in the CDS Data D<SPAN>efinition</SPAN>.&nbsp;</P><P>This week let us go one step further and explore another very interesting feature of Joule's ABAP AI capability -&nbsp; The <STRONG>RAP Business Logic Prediction</STRONG>.</P><P><FONT size="4"><STRONG>Quick Links</STRONG></FONT></P><P><SPAN>Please use&nbsp;</SPAN><A href="https://community.sap.com/t5/abap-forum/questions-march-2026-developer-challenge-joule-for-developers-in-abap/m-p/14342754#M686" target="_self">this separate thread to ask your questions and discuss issues</A>.&nbsp;</P><P><FONT size="4"><STRONG>Sample Scenario</STRONG></FONT></P><P>Here let us think about any simple scenario like changing a field to ‘Mandatory’ and then create a new entry without filling value for this field. Empty values should not be accepted for the mandatory field and we can use the <STRONG>‘validation’</STRONG> keyword to check if its kept empty. Here use Joule’s ‘<STRONG>RAP Predict Business Logic</STRONG>’ capability to suggest the code to raise an error message in the implementation method of the validation function. Let’s see the steps in detail.</P><P><STRONG><U>Task1:</U></STRONG> <STRONG>Create a validation and implement the corresponding method.</STRONG></P><OL><LI>Create a validation in the BDEF of the CDS view. Open your behavior definition and specify one of the fields as mandatory.<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Define Mandatory Field" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/380225iF1D8068A92B37209/image-size/large?v=v2&amp;px=999" role="button" title="Mandatory Field.jpg" alt="Define Mandatory Field" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Define Mandatory Field</span></span></LI><LI>Define the Validation in same BDEF of the CDS view.<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Validation Defenition" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/380226iAE7BE88A40809E7D/image-size/large?v=v2&amp;px=999" role="button" title="Validation Defenition.jpg" alt="Validation Defenition" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Validation Defenition</span></span></LI><LI>In order to have draft instances being checked by validations before they become active, they have to be specified for the&nbsp;<STRONG>draft determine action prepare</STRONG>&nbsp;in the behavior definition. Replace the code line&nbsp;<STRONG>draft determine action Prepare; </STRONG>in your BDEF&nbsp;with the following code snippet as shown on the screenshot below.<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Prepare Action" style="width: 770px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/380227iFC934B9F2CDAD5B2/image-size/large?v=v2&amp;px=999" role="button" title="Prepare Action for Validation.jpg" alt="Prepare Action" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Prepare Action</span></span></LI><LI>Save and activate the changes.</LI><LI>Now you can notice a small icon to the left of the validation definition. Click on it to create the implementation method for adding validation logic in the local handler class&nbsp;of the behavior pool of your entity. Save and activate the changes. <STRONG>Hint:</STRONG> You can right click on the new method name and choose Quick Fix as well.<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Implement Validation" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/380234i167B896BE86066ED/image-size/large?v=v2&amp;px=999" role="button" title="Implement Validation.jpg" alt="Implement Validation" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Implement Validation</span></span>For additional information on Validations and its syntax and use you can refer the BDEF ‘/DMO/R_Travel_D’. Alternatively you can also refer <A href="https://github.com/SAP-samples/abap-platform-rap100/tree/main/exercises/ex05" target="_blank" rel="noopener nofollow noreferrer">https://github.com/SAP-samples/abap-platform-rap100/tree/main/exercises/ex05</A></LI></OL><P><STRONG><U>Task2:</U> Enhance validation with RAP Predict Business Logic</STRONG></P><P>Use Joule's RAP Predict Business Logic to add the logic to check whether the mandatory field created in Task 1 is filled while creating a new entry. If it is left empty throw an error message.</P><P><FONT color="#FF0000">Note:- The logic and examples are mentioned just for your reference and to make the purpose of the challenge easy to understand. Please feel free to use your own logic and dataset.</FONT></P><P>To know how to use&nbsp;<STRONG>RAP Predict Business Logic&nbsp;</STRONG>follow this&nbsp;<A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/rap-business-logic-prediction?locale=en-US#video-tutorial" target="_self" rel="noopener noreferrer">tutorial.&nbsp;</A><STRONG>Hint:</STRONG> You can right click on the new method name and choose Quick Fix as well.</P><P>Good luck and wait for the last challenge next week. Until then Stay Jouled !!!</P> 2026-03-16T05:30:00.017000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/oops-we-did-it-again-a-brand-new-top-level-abap-keyword-in-abap-ce-2602/ba-p/14348431 Oops we did it again! A brand new top-level ABAP keyword in ABAP CE 2602. 2026-03-16T12:43:47.550000+01:00 kilian_kilger https://community.sap.com/t5/user/viewprofilepage/user-id/204709 <H2 id="toc-hId-1791549950">Introduction</H2><P>New ABAP commands arise only once in most people's lifetimes. But after the ABAP command&nbsp;<STRONG>WITH </STRONG>in AS ABAP 7.51, we have now introduced the new ABAP&nbsp;command&nbsp;<STRONG>MERGE</STRONG>.<BR />The fact that both keywords concern databases is no coincidence. Leveraging the full power of the HANA database is one of ABAP's highest priorities.<BR />Note that we use "command" as a synonym for top-level keywords in this article.</P><H2 id="toc-hId-1595036445">Introducing a new ABAP top-level keyword in the 21st century</H2><P>What is the problem with introducing a new ABAP keyword? <STRONG>Macros</STRONG>. Consider the following coding:</P><pre class="lia-code-sample language-abap"><code>DEFINE merge. WRITE : / &amp;1. END-OF-DEFINITION. MERGE 'hello'.</code></pre><P>&nbsp;</P><P>After introducing MERGE as a new keyword, this code would have syntax errors. This is why, for example, RAP avoided introducing any new top-level keyword with <STRONG>EML</STRONG>. MODIFY, READ, COMMIT all existed well before RAP.&nbsp;<BR />But the developers of ABAP SQL are not afraid, as they have already shown in the past. With MERGE, they introduced the concept of a <U><STRONG>weak ABAP keyword</STRONG></U>! Macros take precedence. Here is what happens when you use a macro named MERGE in 2602:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="kilian_kilger_0-1773482798476.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/383422i71B66FE9E6BD9585/image-size/large?v=v2&amp;px=999" role="button" title="kilian_kilger_0-1773482798476.png" alt="kilian_kilger_0-1773482798476.png" /></span></P><P>So despite a number of warnings, nothing bad happens. You cannot use the new ABAP command MERGE in this program, though. There is and will be no escape mechanism.&nbsp;</P><P>Of course, macros are not available in ABAP Cloud and this is only relevant for customers when MERGE makes it into the next On Premise release.</P><H2 id="toc-hId-1398522940">What does MERGE do?</H2><P>MERGE is a standard SQL database command. It exists on the HANA database and most other commercial databases. Practically it is a more powerful version of UPDATE, DELETE, INSERT and MODIFY all in one command.</P><P>As MERGE is an SQL standard keyword and ABAP is a superset of SQL by tradition, we also opted to keep the command name and thus introduce a new ABAP command.&nbsp;</P><P>Conceptually, MERGE is a very easy operation to understand. Here is the flow:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="kilian_kilger_0-1773660530889.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/384137i227276793E498490/image-size/large?v=v2&amp;px=999" role="button" title="kilian_kilger_0-1773660530889.png" alt="kilian_kilger_0-1773660530889.png" /></span></P><P>Here, "when no join partner found" means that the joined table (e.g., internal table) contains a set not contained in the database table. The other direction is not covered yet (see below).</P><H2 id="toc-hId-1202009435">&nbsp;</H2><H2 id="toc-hId-1005495930">A practical example</H2><P>In this section, we give a very easy example of the <STRONG>MERGE</STRONG> command. Say you have a database table of users, and from time to time, you update it from an Excel spreadsheet stored in an internal table.&nbsp;&nbsp;</P><P>A simple merge command would look like follows:</P><pre class="lia-code-sample language-abap"><code>MERGE INTO users USING <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1932364">@Excel</a> AS excel ON users~userid = excel~userid WHEN MATCHED AND users~managed_by_excel = <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/2449">@abap_true</a> THEN UPDATE SET user_data = excel~user_data WHEN NOT MATCHED THEN INSERT ALL.</code></pre><P>&nbsp;This command is really self-explanatory. When you want to change the fields inserted into the database, you can also specify them as expressions in the VALUES ( .... ) clause. The usage of <STRONG>DELETE</STRONG> is fairly similar.</P><P>Some databases (for example SQL Server) have an additional clause <STRONG>WHEN NOT MATCHED&nbsp; BY SOURCE</STRONG>, which is triggered when an entry is found in the joined table (e.g. excel) but not in the target table (e.g. users).&nbsp; This is neither present in ABAP nor on the HANA database yet.&nbsp;<BR />Thus, conceptually, the join equals a RIGHT OUTER JOIN.</P><H2 id="toc-hId-808982425">Summary</H2><P>This article introduces the new ABAP command MERGE, a powerful tool for data manipulation. Due to its ability to join an internal or database table (or a global temporary table for that matter) it can be a very powerful tool in the hands of an ABAP developer.</P><P>You may find additional information in the SAP help article&nbsp;<A href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/ABAPMERGE_DBTAB.html" target="_self" rel="noopener noreferrer">here.</A><SPAN>&nbsp;</SPAN></P> 2026-03-16T12:43:47.550000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/sap-btp-abap-environment-customer-amp-partner-roundtable-april-07-2026/ba-p/14349703 SAP BTP ABAP Environment Customer & Partner Roundtable – April 07, 2026 2026-03-17T09:00:00.021000+01:00 Burcu_Karlidag https://community.sap.com/t5/user/viewprofilepage/user-id/151005 <P>Dear customers, partners, and SAP Community members,</P><P>Join us for the next session of our <STRONG>SAP BTP ABAP Environment Customer &amp; Partner Roundtable</STRONG>, taking place on <STRONG>April 07, 2026, from 10:00–11:00 CET</STRONG>.</P><P>Our roundtable is a monthly virtual meeting where we share the latest updates from the product team and showcase live demos from experts. It is a great opportunity to stay up to date with the latest capabilities of the <STRONG>SAP BTP ABAP Environment</STRONG>, ask questions, and engage with the community.</P><P><STRONG>Join the session</STRONG></P><P><span class="lia-unicode-emoji" title=":calendar:">📅</span><STRONG>Date:</STRONG> April 07, 2026<BR /><span class="lia-unicode-emoji" title=":alarm_clock:">⏰</span><STRONG>Time:</STRONG> 10:00–11:00 CET</P><P><STRONG>Agenda</STRONG></P><P><span class="lia-unicode-emoji" title=":small_blue_diamond:">🔹</span><STRONG>App as an Entity</STRONG> – <EM>Aron Leibfried</EM></P><P><span class="lia-unicode-emoji" title=":small_blue_diamond:">🔹</span><STRONG>Direct App Launch</STRONG> – <EM>Aparna Narayanaswamy</EM></P><P><EM><span class="lia-unicode-emoji" title=":small_blue_diamond:">🔹</span></EM><STRONG>Infrastructure Topics (Smaller Runtime &amp; Costs,&nbsp;Multi-Availability Zones)&nbsp;</STRONG>–&nbsp;<EM>Christian Lutter</EM></P><P><EM><span class="lia-unicode-emoji" title=":small_blue_diamond:">🔹</span><STRONG>Product Updates</STRONG> – Frank Jentsch</EM></P><P>The roundtable is a<SPAN>&nbsp;</SPAN><STRONG>monthly series</STRONG><SPAN>&nbsp;</SPAN>taking place on the<SPAN>&nbsp;</SPAN><STRONG>first Tuesday of every month (10:00–11:00 CET)</STRONG>.</P><P><SPAN class="lia-unicode-emoji"><SPAN class="lia-unicode-emoji"><span class="lia-unicode-emoji" title=":backhand_index_pointing_right:">👉</span>&nbsp;</SPAN></SPAN><STRONG>Download the</STRONG><SPAN>&nbsp;</SPAN><STRONG><A href="https://github.com/iwonahahn/SAP-BTP-ABAP-Environment-Roundtable/releases/download/v26/SAP.BTP.ABAP.Environment.Customer.und.Partner.Roundtable.ics" target="_self" rel="nofollow noopener noreferrer">.ics calendar file</A><SPAN>&nbsp;</SPAN>for the full 2026 series</STRONG><SPAN>&nbsp;and&nbsp;import it directly into your calendar.</SPAN><BR /><SPAN>Each calendar entry already includes the Microsoft Teams meeting link.</SPAN></P><P><SPAN>Microsoft Teams meeting link (valid for the entire 2026 series):&nbsp;<A href="https://teams.microsoft.com/l/meetup-join/19%3ameeting_YTE0YzFlNGMtMDA2NC00NThlLWEzYWQtNWExNzU3MmRmNGE1%40thread.v2/0?context=%7b%22Tid%22%3a%2242f7676c-f455-423c-82f6-dc2d99791af7%22%2c%22Oid%22%3a%223d2a93aa-8f6e-4294-826f-80727ddf8588%22%7d" target="_self" rel="nofollow noopener noreferrer">Microsoft Teams meeting link</A>&nbsp;</SPAN></P><P><SPAN>All agendas, slides, recordings, and updates from past and current sessions are published centrally via the</SPAN><BR /><A href="https://pages.community.sap.com/topics/btp-abap-environment/customer-partner-roundtable" target="_self" rel="noopener noreferrer"><STRONG>SAP Community – SAP BTP ABAP Environment Customer &amp; Partner Roundtable.</STRONG></A></P><P><SPAN>We’re looking forward to seeing you there!</SPAN></P><P><STRONG>SAP BTP ABAP Environment Team</STRONG></P> 2026-03-17T09:00:00.021000+01:00 https://community.sap.com/t5/abap-blog-posts/how-to-create-a-rap-application-using-a-parameterized-cds-view/ba-p/14332860 How to create a RAP application using a parameterized CDS view 2026-03-17T10:38:18.358000+01:00 _Kayky_Mattos_ https://community.sap.com/t5/user/viewprofilepage/user-id/885395 <P>Hello everyone, recently I came across a somewhat unusual requirement where I needed to use a parameter in a RAP application. As we know, this isn’t natively supported with Fiori Elements, so I had to look for a way to make it work. After some research and a few tests, I ended up with a solution that I consider quite innovative: using a Fiori Freestyle approach.</P><P>The best part is that it requires only a minimal amount of code, something that any ABAP developer can implement without much effort, and it becomes extremely useful whenever you need to work with parameters that are not directly linked to the data exposed by the CDS view.</P><P>The idea behind this solution is simple:</P><P>Since projection views in RAP do not support CDS parameters directly, we expose a parameterized interface CDS view through a service definition and service binding.</P><P>Then, using a Fiori Freestyle application with a Smart Table, we dynamically inject the parameter into the table binding path before the data request is sent to the backend.</P><P>This allows the RAP service to consume the parameterized CDS view without requiring complex workarounds.</P><P>&nbsp;</P><P>Let’s go through the required steps:</P><P>&nbsp;</P><P>1)&nbsp;&nbsp;Since it’s not possible to add <EM>WITH PARAMETERS</EM> to a projection view, we need to create an interface CDS view and use it as our “projection.”</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matttosz_2-1771590856902.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374759i98B6303DAD9181A7/image-size/medium?v=v2&amp;px=400" role="button" title="matttosz_2-1771590856902.png" alt="matttosz_2-1771590856902.png" /></span></P><pre class="lia-code-sample language-abap"><code>@AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: '&lt;your cds description&gt;' @Metadata.ignorePropagatedAnnotations: false @Metadata.allowExtensions: true define view entity &lt;your_parameterized_interface_cds&gt; with parameters p_date : abap.char(8) as select from &lt;your_source_cds_or_table&gt; ( p_date : $parameters.p_date ) { key &lt;your_key_field&gt;, &lt;your_field_1&gt;, &lt;your_field_2&gt;, &lt;your_field_3&gt; }</code></pre><P>2) Create our service definition normally</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matttosz_4-1771591575874.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374773iA5AEE40CC9D85AE3/image-size/medium?v=v2&amp;px=400" role="button" title="matttosz_4-1771591575874.png" alt="matttosz_4-1771591575874.png" /></span></P><P>3) Create Service Binding ( Odata V2 )</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matttosz_5-1771591628061.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374774i451EFA45F05042DF/image-size/medium?v=v2&amp;px=400" role="button" title="matttosz_5-1771591628061.png" alt="matttosz_5-1771591628061.png" /></span></P><P>4) Now we have to create the freestyle app with the fiori generator application</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matttosz_6-1771591700764.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374775i8579D8356C446085/image-size/medium?v=v2&amp;px=400" role="button" title="matttosz_6-1771591700764.png" alt="matttosz_6-1771591700764.png" /></span></P><P>5) Now just connect to the S4 and select the service binding created earlier</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matttosz_7-1771591755516.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374776iED1814F045E94A2F/image-size/medium?v=v2&amp;px=400" role="button" title="matttosz_7-1771591755516.png" alt="matttosz_7-1771591755516.png" /></span></P><P>At this point, you can see the project structure in the Explorer panel on the left. We’ll focus only on the <EM>view</EM> and <EM>controller</EM> folders.</P><P>&nbsp;</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matttosz_2-1771594013215.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374794i835B647EA4E7E861/image-size/medium?v=v2&amp;px=400" role="button" title="matttosz_2-1771594013215.png" alt="matttosz_2-1771594013215.png" /></span></P><P>&nbsp;</P><P>6)</P><P>First, we need to create our Smart Table in the <STRONG>view</STRONG> folder. Inside the <STRONG>SmartFilterBar</STRONG>, we must set the <CODE>entitySet</CODE> from our service binding. After that, we add a <CODE>customControl</CODE>&nbsp;in my case, I used a <STRONG>DatePicker</STRONG>, but you can use any control that fits your requirement. I also attached an <CODE>onDateChange</CODE> event to the DatePicker so we can capture and manipulate the selected date whenever it changes.</P><P>Within the <STRONG>Smart Table</STRONG>, we also need to define the same <CODE>entitySet</CODE>. Another very important point here is the <CODE>beforeRebindTable</CODE> event. This is the hook that allows us to pass the parameter to the CDS view. It will trigger the <CODE>onBeforeRebindTable</CODE> method in the controller, where we can dynamically inject the parameter into the binding before the data is requested.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matttosz_3-1771594045964.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374795i890A0F22CFECFBAA/image-size/medium?v=v2&amp;px=400" role="button" title="matttosz_3-1771594045964.png" alt="matttosz_3-1771594045964.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matttosz_10-1771592364211.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374781i3F840A283FD3C8AD/image-size/medium?v=v2&amp;px=400" role="button" title="matttosz_10-1771592364211.png" alt="matttosz_10-1771592364211.png" /></span></P><pre class="lia-code-sample language-markup"><code>&lt;mvc:View xmlns:table="sap.ui.table" xmlns="sap.ui.comp.smartfilterbar" xmlns:f="sap.f" xmlns:m="sap.m" xmlns:mvc="sap.ui.core.mvc" xmlns:smartTable="sap.ui.comp.smarttable" controllerName="&lt;your.app.namespace&gt;.controller.Main" height="100%"&gt; &lt;f:DynamicPage id="dynamicPage" fitContent="true" title="{i18n&gt;appTitle}"&gt; &lt;f:header&gt; &lt;f:DynamicPageHeader&gt; &lt;SmartFilterBar id="smartFilterBar" entitySet="&lt;your_entity_set&gt;"&gt; &lt;controlConfiguration&gt; &lt;ControlConfiguration key="&lt;your_parameter_field&gt;" visibleInAdvancedArea="true" label="&lt;your_filter_label&gt;" mandatory="true"&gt; &lt;customControl&gt; &lt;m:DatePicker id="datePicker" displayFormat="dd/MM/yyyy" valueFormat="yyyyMMdd" placeholder="dd/mm/yyyy" width="100%" required="true" change="onDateChange"/&gt; &lt;/customControl&gt; &lt;/ControlConfiguration&gt; &lt;/controlConfiguration&gt; &lt;/SmartFilterBar&gt; &lt;/f:DynamicPageHeader&gt; &lt;/f:header&gt; &lt;f:content&gt; &lt;smartTable:SmartTable id="smartTable" beforeRebindTable="onBeforeRebindTable" showRowCount="true" enableAutoBinding="false" entitySet="&lt;your_entity_set&gt;" smartFilterId="smartFilterBar" useVariantManagement="true" tableType="Table" initiallyVisibleFields="&lt;your_fields&gt;" enableAutoColumnWidth="true" showTablePersonalisation="true"&gt; &lt;smartTable:customToolbar&gt; &lt;m:OverflowToolbar design="Transparent"&gt; &lt;m:ToolbarSpacer/&gt; &lt;/m:OverflowToolbar&gt; &lt;/smartTable:customToolbar&gt; &lt;/smartTable:SmartTable&gt; &lt;/f:content&gt; &lt;/f:DynamicPage&gt; &lt;/mvc:View&gt;</code></pre><P>7) In this step, we implement the logic inside the <STRONG><CODE>onBeforeRebindTable</CODE></STRONG> method, which is responsible for dynamically passing the parameter to the CDS view before the Smart Table triggers the data request.</P><P>First, the code retrieves the value entered in the <STRONG>DatePicker</STRONG> using <CODE>byId</CODE>. This value will be used as the parameter for the CDS. A local variable (<CODE>sDate</CODE>) is initialized to store the selected date.</P><P>Next, a validation is performed to ensure that the date field is filled in. Since this parameter is mandatory for the query, if no value is provided the DatePicker is set to the <STRONG>Error</STRONG> state and a validation message is displayed. At the same time, the table binding is stopped using:</P><P><CODE>oBindingParams.preventTableBind = true;</CODE></P><P>This prevents the Smart Table from calling the backend without the required parameter, avoiding unnecessary requests and possible errors.</P><P>If the date is correctly filled in, any previous error state is cleared by setting the ValueState back to <STRONG>None</STRONG>.</P><P>Finally, the most important part happens: the table binding path is updated dynamically. Here we pass the selected date to the parameterized CDS by changing the binding path of the Smart Table:</P><P><CODE>setTableBindingPath("/&lt;EntitySet&gt;(p_date='${sDate}')/Set")</CODE></P><P>This is what allows the RAP application to consume a <STRONG>CDS with parameters</STRONG>, because the parameter is injected at runtime just before the data is requested from the backend.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matttosz_12-1771593060014.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374786iF7D8D4780A379928/image-size/medium?v=v2&amp;px=400" role="button" title="matttosz_12-1771593060014.png" alt="matttosz_12-1771593060014.png" /></span></P><pre class="lia-code-sample language-javascript"><code>onBeforeRebindTable: function (oEvent) { let oDatePicker = this.byId("datePicker"); let sDate = ""; if (oDatePicker) { sDate = oDatePicker.getValue(); } if (!sDate) { if (oDatePicker) { oDatePicker.setValueState("Error"); oDatePicker.setValueStateText("Please inform the date."); } let oBindingParams = oEvent.getParameter("bindingParams"); if (oBindingParams) { oBindingParams.preventTableBind = true; } return; } if (oDatePicker) { oDatePicker.setValueState("None"); } this.getView() .byId("smartTable") .setTableBindingPath("/&lt;your_entity_set&gt;(p_date='" + sDate + "')/Set"); }</code></pre><P>And&nbsp;<SPAN>Vooooalá!</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="matttosz_13-1771593754921.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/374791iB89691EFDEECC4B4/image-size/medium?v=v2&amp;px=400" role="button" title="matttosz_13-1771593754921.png" alt="matttosz_13-1771593754921.png" /></span></P><P>Conclusion</P><P>Although RAP and Fiori Elements provide powerful tools for building enterprise applications, there are still scenarios where certain features are not directly supported, such as consuming parameterized CDS views in projection layers.</P><P>By combining RAP services with a lightweight Fiori Freestyle approach, we can overcome this limitation in a simple and flexible way. Using events like beforeRebindTable and dynamically modifying the binding path allows parameters to be passed to the CDS view at runtime.</P><P>This approach requires only a small amount of additional UI code and can be implemented quickly by ABAP developers who are already familiar with RAP and Fiori.</P><P>I hope this solution helps others facing similar challenges when working with parameterized CDS views in RAP applications.</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P> 2026-03-17T10:38:18.358000+01:00 https://community.sap.com/t5/technology-blog-posts-by-members/rap-unmanaged-draft-early-numbering-and-associations-for-unique-ids/ba-p/14351767 RAP Unmanaged Draft: Early Numbering and Associations for Unique IDs 2026-03-19T15:23:41.063000+01:00 vidyadharsp https://community.sap.com/t5/user/viewprofilepage/user-id/1913267 <P><FONT size="5" color="#808080"><STRONG>INTRODUCTION</STRONG></FONT></P><P>In RAP,&nbsp;Implementing&nbsp;numbering&nbsp;mechanisms during these operations is essential to ensure unique identifiers for newly created entities.<BR />This blog is exposure the best for numbering during Creation and Creation by Association, in Unmanaged Scenario with Draft. How to handle number creation with Draft Scenario's.</P><P><U><STRONG><FONT size="4">Some Information about Numbering<BR /></FONT></STRONG></U>Basically, Numbering is the concept to process assigning unique values to the key fields of business entities during Create and Create By Association Operations.<BR /><BR /><U><STRONG>Unmanaged Early Numbering:</STRONG></U></P><UL><LI>Developers need to implement custom code logic to create and assign keys values during the creation and create by association operation.&nbsp;</LI><LI><STRONG><SPAN>%is_draft</SPAN></STRONG><SPAN>&nbsp;– It is a&nbsp;component&nbsp;of the transactional key (%tky) in RAP.</SPAN><SPAN>&nbsp;</SPAN><UL><LI><SPAN>It tells the framework whether to&nbsp;operate&nbsp;on the draft table or the active persistent table for a given operation.</SPAN><SPAN>&nbsp;</SPAN></LI><LI><SPAN>%is_draft&nbsp;=&nbsp;mk-on reads from draft table</SPAN><SPAN>&nbsp;</SPAN></LI><LI><SPAN>%is_draft&nbsp;=&nbsp;mk-off reads from active table</SPAN><SPAN>&nbsp;</SPAN></LI></UL></LI></UL><P><FONT color="#FF0000"><U><STRONG>Problem Statement</STRONG></U></FONT></P><P><FONT color="#000000">A sales clerk begins creating a Sales Order in Fiori. The order header is saved as a draft, but items need to be added immediately under that draft. To ensure consistency, the system must generate a unique Sales Order ID right away and assign incremental item numbers without waiting for activation.</FONT></P><P><SPAN><STRONG>Importance</STRONG>:</SPAN></P><UL><LI><P><SPAN>Early numbering guarantees <STRONG>unique identification</STRONG> across drafts and active records.</SPAN></P></LI><LI><P><SPAN>Associations ensure <STRONG>header–item linkage</STRONG> is preserved.</SPAN></P></LI><LI><P><SPAN>Draft handling allows users to <STRONG>save incomplete transactions safely</STRONG> and activate later without losing data integrity.</SPAN></P></LI></UL><P><U><STRONG>Behavior Definition of Root Entity</STRONG></U></P><P><CODE>early numbering</CODE> → enables key generation during root creation.</P><pre class="lia-code-sample language-abap"><code>unmanaged implementation in class zbp_i_vd_head unique; strict ( 2 ); with draft; define behavior for ZI_VD_HEAD alias Header draft table zdft_vd_head lock master total etag CreatedOn authorization master ( instance ) early numbering // Early numbering declaration in root entity { create; update; delete; association _item { create; } field ( readonly : update ) CustNo; draft action Edit; draft action Activate optimized; draft action Resume; draft action Discard; draft determine action Prepare; } mapping for zvd_t_hsale { CustNo = cust_no; SalesOrder = sales_order; CreatedOn = created_on; EntryTime = entry_time; Name = name; DocCat = doc_cat; }</code></pre><P><BR /><U><STRONG>Behavior Definition of Item Entity</STRONG></U></P><P><CODE>early numbering</CODE> → enables key generation during item creation.</P><pre class="lia-code-sample language-abap"><code>define behavior for ZI_VD_ITEM alias Item draft table zdft_vd_item lock dependent by _head authorization dependent by _head early numbering // Early numbering declaration in item entity { update; delete; field ( readonly ) CustNo; association _head; mapping for zvd_t_isale { CustNo = cust_no; SalesOrder = sales_order; DocItem = doc_item; MatNumber = mat_number; MatGroup = mat_group; CreatedOn = created_on; } }</code></pre><P><U><STRONG>Behavior Pool Implementation</STRONG></U></P><P>This method ensures that every new entity gets a unique identifier (<CODE>CustNo</CODE>) during creation if it wasn’t already provided.</P><P><STRONG>UUID Generation:</STRONG></P><UL><LI><P><CODE>cl_system_uuid=&gt;create_uuid_x16_static( )</CODE> generates a globally unique key.</P></LI><LI><P>This avoids collisions and guarantees uniqueness across drafts and active records.</P></LI></UL><P><U><STRONG>Mapped Root:</STRONG></U></P><UL><LI><P><CODE>%cid</CODE> → correlates client-side temporary IDs with backend entities.</P></LI><LI><P><CODE>%key</CODE> → holds the generated or existing key.</P></LI><LI><P><CODE>%is_draft</CODE> → ensures draft state is preserved.</P></LI><LI><P><CODE>CustNo</CODE> → the actual business key stored in the entity.</P></LI></UL><pre class="lia-code-sample language-abap"><code>METHOD earlynumbering_create. LOOP AT entities INTO DATA(entity). DATA(lv_custno) = entity-custno. IF lv_custno IS INITIAL. TRY. lv_custno = cl_system_uuid=&gt;create_uuid_x16_static( ). CATCH cx_uuid_error. "handle exception ENDTRY. ENDIF. APPEND VALUE #( %cid = entity-%cid %key = VALUE #( custno = lv_custno ) %is_draft = entity-%is_draft custno = lv_custno ) TO mapped-header. ENDLOOP. ENDMETHOD.</code></pre><P><STRONG>Mapped Item:</STRONG></P><P>This method handles early numbering when creating items via association (<CODE>CREATE-BY-ASSOCIATION</CODE>).</P><UL><LI><P>First, it retrieves the maximum <CODE>cust_no</CODE> from the database table <CODE>zvd_t_isale</CODE> for the current entity.</P></LI></UL><UL><LI><P><CODE>%cid</CODE> → client-side correlation ID.</P></LI><LI><P><CODE>%key</CODE> → generated key with <CODE>CustNo</CODE>.</P></LI><LI><P><CODE>%is_draft</CODE> → preserves draft state.</P></LI><LI><P><CODE>CustNo</CODE> → ensures linkage to the root entity.</P></LI></UL><pre class="lia-code-sample language-abap"><code>METHOD earlynumbering_cba_item. LOOP AT entities INTO DATA(entity). " Get current max Customer Number from DB SELECT MAX( cust_no ) INTO (lv_max) FROM zvd_t_isale WHERE cust_no = -%key-custno. LOOP AT entity-%target INTO DATA(t_item). APPEND VALUE #( %cid = t_item-%cid %key = VALUE #( custno = entity-%key-custno ) %is_draft = t_item-%is_draft custno = entity-%key-custno ) TO mapped-item. ENDLOOP. ENDLOOP. ENDMETHOD.</code></pre><UL><LI><P>Item inherits lock and authorization from the header.</P></LI><LI><P>Early numbering ensures item keys are generated consistently.</P></LI><LI><P>Association links items back to the header BO.</P></LI></UL><P><U><STRONG>Persistence Methods</STRONG></U></P><UL class="lia-list-style-type-square"><LI><U><STRONG>Create Method</STRONG></U></LI></UL><pre class="lia-code-sample language-abap"><code>METHOD create. LOOP AT entities INTO DATA(entity). DATA(header) = CORRESPONDING zvd_t_hsale( entity MAPPING FROM ENTITY ). header-created_on = sy-datum. header-entry_time = sy-datum. header-name = sy-uname. APPEND header TO gt_hsale. ENDLOOP. ENDMETHOD.</code></pre><UL><LI><U><STRONG>Create-By-Association Method</STRONG></U></LI></UL><pre class="lia-code-sample language-abap"><code>METHOD cba. LOOP AT entities_cba INTO DATA(entity_cba). LOOP AT entity_cba-%target INTO DATA(target_item). DATA(item) = CORRESPONDING zvd_t_isale( target_item MAPPING FROM ENTITY ). item-cust_no = entity_cba-%key-CustNo. item-created_on = sy-datum. APPEND item TO gt_isale. ENDLOOP. ENDLOOP. ENDMETHOD.</code></pre><P><U><STRONG>Result</STRONG></U></P><P><U><STRONG><span class="lia-inline-image-display-wrapper lia-image-align-left" image-alt="o1.png" style="width: 975px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/385288i3FC295D0198CCAE8/image-size/large?v=v2&amp;px=999" role="button" title="o1.png" alt="o1.png" /></span></STRONG></U></P><P>&nbsp;</P><P>&nbsp;</P><H2 id="toc-hId-1792267916">&nbsp;</H2><H2 id="toc-hId-1595754411">&nbsp;</H2><H2 id="toc-hId-1399240906">&nbsp;</H2><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P><FONT size="5" color="#999999"><STRONG>Conclusion</STRONG></FONT></P><P><SPAN>By combining <STRONG>Draft Handling, Associations, and Early Numbering</STRONG>, RAP unmanaged scenarios can support complex business objects like Sales Orders, Purchase Orders. This approach ensures flexibility, control, and consistency in transactional applications.<BR /><BR />Thank You...</SPAN></P> 2026-03-19T15:23:41.063000+01:00 https://community.sap.com/t5/technology-blog-posts-by-members/link-handlers-cannot-be-registered-as-the-application-is-signed-eclipse-mac/ba-p/14350162 Link Handlers cannot be registered as the application is signed - Eclipse MAC 2026-03-19T16:11:34.391000+01:00 fez-4u_ https://community.sap.com/t5/user/viewprofilepage/user-id/2287668 <H2 id="toc-hId-1792232354">What Are Link Handlers?</H2><P>When you click an <CODE>adt://</CODE> link somewhere — SAP GUI, a wiki, a colleague's message — macOS needs to figure out which app should open it. That mapping is handled by link handlers.</P><P>In Eclipse, you find them under <STRONG>Preferences → General → Link Handlers</STRONG>. Two entries matter for ABAP developers:</P><UL><LI><CODE>adt</CODE> – How <CODE>adt://</CODE> links open ABAP objects (classes, programs, etc.) in your Eclipse workspace.</LI><LI><CODE>eclipse+command</CODE> – Lets URLs trigger Eclipse commands, like opening a specific view.</LI></UL><P>Both should show a checked box and <STRONG>"This application"</STRONG> in the Handler column. If you only have one Eclipse on your Mac, you might never notice a problem. But with two installations (say one for ABAP, one for Java), wrong link routing gets annoying fast.</P><H2 id="toc-hId-1595718849">The Problem</H2><P>You open Link Handlers and see this at the top:</P><BLOCKQUOTE><STRONG><span class="lia-unicode-emoji" title=":no_entry:">⛔</span>Link Handlers cannot be registered as the application is signed.</STRONG></BLOCKQUOTE><P>Checkboxes grayed out. Handler column says "Other application." Sometimes you also get this when clicking around the page:</P><PRE>Cannot invoke "org.eclipse.urischeme.ISchemeInformation.schemeIsHandledByOther()" because "schemeInfo.information" is null</PRE><P>You click an <CODE>adt://</CODE> link and either the wrong Eclipse opens, or nothing happens.</P><H2 id="toc-hId-1399205344">Why This Happens on macOS</H2><P>macOS maps URL schemes to apps using the <CODE>Info.plist</CODE> inside each app bundle (<CODE>/Applications/Eclipse.app/Contents/Info.plist</CODE>). A key called <CODE>CFBundleURLTypes</CODE> lists which schemes the app claims. macOS reads it and stores the mapping in its Launch Services database. On top of that, plugins like ADT can also register schemes at runtime.</P><P>Here's where it breaks. Eclipse ships code-signed. The signature covers the entire bundle, including Info.plist. When Eclipse tries to modify the plist at runtime to register a scheme, macOS blocks it because that would invalidate the signature. The Link Handlers page sees the restriction and grays everything out.</P><H2 id="toc-hId-1202691839">The Fix</H2><P>Two parts to this: first, make sure your Info.plist has the right URL scheme entries, then fix the code signature that's blocking everything.</P><P><STRONG><span class="lia-unicode-emoji" title=":warning:">⚠️</span>Close Eclipse before you start.</STRONG></P><H3 id="toc-hId-1135261053">Step 1: Check your Info.plist for CFBundleURLTypes</H3><P>Open the plist:</P><PRE>sudo nano /Applications/Eclipse.app/Contents/Info.plist</PRE><P>Look for a <CODE>CFBundleURLTypes</CODE> key. The default Eclipse plist usually already has <CODE>eclipse+command</CODE> and <CODE>eclipse+mpc</CODE>, but not <CODE>adt</CODE>. You need all three in a single <CODE>CFBundleURLTypes</CODE> array. If the key already exists, add the <CODE>adt</CODE> entry into the existing array. If it's missing entirely, add this block just before the closing <CODE>&lt;/dict&gt;</CODE> at the end of the file:</P><PRE>&lt;key&gt;CFBundleURLTypes&lt;/key&gt; &lt;array&gt; &lt;dict&gt; &lt;key&gt;CFBundleURLName&lt;/key&gt; &lt;string&gt;Eclipse Command&lt;/string&gt; &lt;key&gt;CFBundleURLSchemes&lt;/key&gt; &lt;array&gt; &lt;string&gt;eclipse+command&lt;/string&gt; &lt;/array&gt; &lt;/dict&gt; &lt;dict&gt; &lt;key&gt;CFBundleURLName&lt;/key&gt; &lt;string&gt;Eclipse Marketplace&lt;/string&gt; &lt;key&gt;CFBundleURLSchemes&lt;/key&gt; &lt;array&gt; &lt;string&gt;eclipse+mpc&lt;/string&gt; &lt;/array&gt; &lt;/dict&gt; &lt;dict&gt; &lt;key&gt;CFBundleURLName&lt;/key&gt; &lt;string&gt;ADT Link Handler&lt;/string&gt; &lt;key&gt;CFBundleURLSchemes&lt;/key&gt; &lt;array&gt; &lt;string&gt;adt&lt;/string&gt; &lt;/array&gt; &lt;/dict&gt; &lt;/array&gt;</PRE><P>Save and exit (<CODE>Ctrl+O</CODE>, then <CODE>Ctrl+X</CODE>).</P><P><STRONG>Important:</STRONG> Make sure there's only <STRONG>one</STRONG> <CODE>CFBundleURLTypes</CODE> key in the entire file. If you're adding the <CODE>adt</CODE> entry to an existing array, don't create a second <CODE>CFBundleURLTypes</CODE> block — duplicate keys in a plist don't merge. macOS only reads one of them, and you'll get unpredictable results. I made this mistake editing in nano and it caused the <CODE>schemeInfo.information is null</CODE> error.</P><H3 id="toc-hId-938747548">Step 2: Remove the existing code signature</H3><PRE>sudo codesign --remove-signature /Applications/Eclipse.app</PRE><P><STRONG>Don't try to open Eclipse after this.</STRONG> macOS won't launch an unsigned app. Move straight to Step 3.</P><H3 id="toc-hId-742234043">Step 3: Re-sign with an ad-hoc signature</H3><PRE>sudo codesign --force --deep --sign - /Applications/Eclipse.app</PRE><P>The <CODE>-</CODE> means ad-hoc — no developer certificate needed. <CODE>--deep</CODE> signs all the nested binaries inside the bundle too.</P><H3 id="toc-hId-545720538">Step 4: Re-register with Launch Services</H3><PRE>/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -R -f /Applications/Eclipse.app</PRE><P>Tells macOS to re-read the app bundle and update its URL scheme mappings.</P><H3 id="toc-hId-349207033">Step 5: Open Eclipse and check</H3><P>Go to <STRONG>Preferences → General → Link Handlers</STRONG>. Both <CODE>adt</CODE> and <CODE>eclipse+command</CODE> should now show checked and marked <STRONG>"This application"</STRONG>.</P><H3 id="toc-hId-152693528">All terminal commands together</H3><PRE># Close Eclipse first, then: sudo codesign --remove-signature /Applications/Eclipse.app sudo codesign --force --deep --sign - /Applications/Eclipse.app /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -R -f /Applications/Eclipse.app # Open Eclipse → Preferences → Link Handlers</PRE><H2 id="toc-hId-174351661">What I Tried That Didn't Work</H2><P>Sharing these so you don't waste time on the same dead ends.</P><P><STRONG>Re-signing without removing first.</STRONG> Tried just running <CODE>codesign --force --deep --sign -</CODE> on its own. Didn't help. The old signature's restrictions stuck around somehow. You have to remove first, then sign fresh.</P><P><STRONG>Duplicate CFBundleURLTypes keys in the plist.</STRONG> This one cost me the most time. When editing in nano, I accidentally added a second <CODE>CFBundleURLTypes</CODE> block instead of adding entries into the existing one. Plist files don't merge duplicate keys — macOS only reads one of them. The result was the <CODE>schemeInfo.information is null</CODE> error, and <CODE>eclipse+command</CODE> stayed stuck on "Other application." If you see that error, open the plist and check for duplicate keys.</P><P><STRONG>Running lsregister by itself.</STRONG> Doesn't do anything useful if the signature is still blocking registration. Necessary as a final step, but not enough on its own.</P><H2 id="toc-hId--22161844">Environment</H2><P>Tested on Eclipse 2025-03 (4.39) with ADT on macOS. Should work the same on any recent Eclipse version where you see the signed-application warning.</P> 2026-03-19T16:11:34.391000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/object-release-state-in-cloudification-repository-viewer-for-clean-core/ba-p/14350668 Object Release State in Cloudification Repository Viewer for Clean Core Extensibility 2026-03-20T08:14:22.285000+01:00 PrasanthPadmanabhan https://community.sap.com/t5/user/viewprofilepage/user-id/824 <H1 id="toc-hId-1663154446">Introduction</H1><P data-unlink="true">The updated <A href="https://www.sap.com/documents/2024/09/20aece06-d87e-0010-bca6-c68f7e60039b.html" target="_blank" rel="noopener noreferrer">Clean Core Extensibility whitepaper</A> was introduced in August 2025 by SAP as an evolution of the 3-Tier Extensibility concept. This updated the 3-Tier Extensibility to a <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/abap-extensibility-guide-clean-core-for-sap-s-4hana-cloud-august-2025/ba-p/14175399" target="_self">more detailed assessment of classic ABAP extensions based on the clean core level concept</A>, allowing you as SAP customers and partners stepwise transformation to clean core at your own pace&nbsp;.</P><P>While using external APIs in your ABAP custom code, one of the first things to check as per the updated level concept is the release state of that API in the <A href="https://sap.github.io/abap-atc-cr-cv-s4hc/" target="_self" rel="nofollow noopener noreferrer">Cloudification Repository Viewer</A>. The release state tells you how stable the object is, what contractual guarantee SAP provides for it, and how your ATC checks will treat any usage of it. Getting this right is important because it directly affects your clean core compliance and your upgrade readiness.</P><P>SAP categorizes all objects in the Cloudification Repository Viewer into five distinct states. Each state carries a specific meaning for your custom code, and knowing the difference will help you make better decisions when selecting or replacing APIs.</P><H2 id="toc-hId-1595723660">The Five Release States in the Cloudification Repository Viewer</H2><P>Here is what each state means in practice and what you should do when you encounter it.</P><H3 id="toc-hId-1528292874">Released</H3><P>A Released API is one that SAP has formally published with a stability contract. Backward compatibility is guaranteed across upgrades, so you can build on these objects with confidence. Released APIs correspond to clean core Level A.</P><P>Level A objects are 100% Cloud compliant, 100% Clean core, can be achieved On-Stack, Side-by-Side or Hybrid.</P><P>If you are starting new development, Released APIs are your first choice. They represent the safest and most future-proof option available to you.</P><H3 id="toc-hId-1331779369">Deprecated</H3><P>A Deprecated API was once Released but SAP is now phasing it out. It still functions today, but it has a planned end of life. SAP recommends that you do not start any new development on it.</P><P>If your existing code already uses a Deprecated object, that code is treated as clean core Level B and flagged as Priority 3 in ATC checks. Make sure to identify the successor API in the Cloudification Repository or the SAP Business Accelerator Hub and plan your migration. The sooner you move away from a Deprecated API, the less remediation work you will face when the object reaches its end-of-life date.</P><H3 id="toc-hId-1135265864">Classic API</H3><P>Classic APIs are well-known, time-tested objects such as BAPIs and RFC-enabled function modules that SAP product experts nominated before a formal release process existed. They do not carry a formal stability contract, but they are upgrade stable and widely used across the SAP ecosystem.</P><P>Classic APIs correspond to clean core Level B and are flagged as Priority 3 in ATC checks. Keep in mind that while these objects are stable in practice, they do not carry the same forward-compatibility guarantee as Released APIs. Use them when no Released alternative is available and check the Cloudification Repository Viewer for the availability of the Released APIs as successors to Classic APIs.</P><H3 id="toc-hId-938752359">Not to be Released</H3><P>An API marked as Not to be Released is one that SAP has explicitly decided is not intended for external use. Any exemption for using such an object must include a migration plan toward a Released API.</P><P>These objects correspond to clean core Level C depending on the context and are flagged as Priority 2 in ATC checks. If you encounter this state, treat it as a signal to find a supported alternative as quickly as possible.</P><H3 id="toc-hId-742238854">No API</H3><P>An object classified as No API has no API contract whatsoever. Objects classified as noAPI must not be used, creates maximum technical debt.</P><P>This state is flagged as Priority 1 in ATC checks and must be addressed at the highest priority. If you find a noAPI object in your custom code, replacing it with a Released API must be your immediate next step.</P><H2 id="toc-hId-416642630">Why Some APIs Are Listed as Both Released and Classic or Not to be Released and Classic</H2><P>You may come across a scenario in the Cloudification Repository Viewer where the same API appears under both the Classic API and Released API categories or Not to be Released and Classic. This is a valid situation and worth understanding, because it can cause some confusion at first glance.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PrasanthPadmanabhan_0-1773990404596.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386665i31AB62038CB9CD55/image-size/large?v=v2&amp;px=999" role="button" title="PrasanthPadmanabhan_0-1773990404596.png" alt="PrasanthPadmanabhan_0-1773990404596.png" /></span></P><P>&nbsp;</P><P>Take the CDS view I_EARMARKEDFUNDSDOCUMENTITEM as an example. If you check this object in the Cloudification Repository Viewer for the 2022 SP0 release of SAP Cloud ERP Private, it is listed only as a Classic API. When you switch to the 2025 FPS01 release, it appears as both Classic API and Released API.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PrasanthPadmanabhan_1-1773990404598.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386663i65DF27FFC9E6A3FC/image-size/large?v=v2&amp;px=999" role="button" title="PrasanthPadmanabhan_1-1773990404598.png" alt="PrasanthPadmanabhan_1-1773990404598.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PrasanthPadmanabhan_2-1773990404601.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386664i6BC6E288F278C856/image-size/large?v=v2&amp;px=999" role="button" title="PrasanthPadmanabhan_2-1773990404601.png" alt="PrasanthPadmanabhan_2-1773990404601.png" /></span></P><P>&nbsp;</P><P>What this tells you is that I_EARMARKEDFUNDSDOCUMENTITEM was formally Released in the 2025 FPS0 release of SAP Cloud ERP Private.</P><P>Both statuses are equally valid for this object. It carries the historical stability of a Classic API and now also has a formal stability contract as a Released API. In this case, the clean core status will be Level A as Released API will take the precedence and ATC check will not give any message.</P><P>Similarly, take the Class CL_HTTP_UTILITY as an example. If you check this object in the Cloudification Repository Viewer for the 2022 SP0 release of SAP Cloud ERP Private, it is listed only as a Classic API. When you switch to the 2025 FPS0 release, it appears as both Classic API and Not to be Released, with a successor.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PrasanthPadmanabhan_5-1773990519687.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386668i4B3DE90044BDD362/image-size/large?v=v2&amp;px=999" role="button" title="PrasanthPadmanabhan_5-1773990519687.png" alt="PrasanthPadmanabhan_5-1773990519687.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PrasanthPadmanabhan_6-1773990537037.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/386669i756C517272C3D19C/image-size/large?v=v2&amp;px=999" role="button" title="PrasanthPadmanabhan_6-1773990537037.png" alt="PrasanthPadmanabhan_6-1773990537037.png" /></span></P><P>Both statuses are equally valid for this object. It carries the historical stability of a Classic API and now also has a formal stability contract as a Not to be Released, with a successor.</P><P>In this case, the clean core status will be Level B as Classic API will take the precedence and ATC check will give a Priority 3 message. You are recommended to move to the successor API in this case.</P><P>This is why it is recommended to check the Cloudification Repository Viewer against the specific release you are working with.</P><H2 id="toc-hId-220129125">Conclusion</H2><P>The Cloudification Repository Viewer continues to grow with each release as SAP adds more objects and updates their states. Use it as your starting point before selecting any API in your custom code. Checking the release state upfront will save you significant remediation work during upgrade cycles and help you stay clean core compliant from day one.</P><P>We will continue to share updates on clean core extensibility as the tooling and API landscape evolves. In the meantime, refer to the Cloudification Repository Viewer and the SAP Business Accelerator Hub for the latest state of the objects relevant to your development.</P> 2026-03-20T08:14:22.285000+01:00 https://community.sap.com/t5/abap-blog-posts/week-4-use-joule-predictive-code-completion-to-implement-determination/ba-p/14342788 Week 4 : Use Joule Predictive Code Completion to Implement Determination 2026-03-23T05:30:00.019000+01:00 sheenamk https://community.sap.com/t5/user/viewprofilepage/user-id/142394 <P>Congratulations to everyone who came along with us till the 4th week of the ABAP Developer Challenge. So far we have seen :</P><UL><LI>How to create a OData UI Service from Scratch using Joule Chat</LI><LI>How to use Joule - Explain feature to understand a block of code.</LI><LI>How to use Joule - RAP Predict Business Logic to create logic for specific tasks.</LI></UL><P>Let us wrap up with another interesting feature of Joule's ABAP AI Capability - The <STRONG>Joule&nbsp;Predictive Code Completion.</STRONG></P><P><FONT size="4"><STRONG>Quick Links</STRONG></FONT></P><P><SPAN>Please use&nbsp;</SPAN><A href="https://community.sap.com/t5/abap-forum/questions-march-2026-developer-challenge-joule-for-developers-in-abap/m-p/14342754#M686" target="_self">this separate thread to ask your questions and discuss issues</A>.&nbsp;</P><P><STRONG>Sample Scenario</STRONG></P><P>We had asked you to create a field of type 'Date' during the RAP application creation.</P><P>Now let us use <STRONG>Determination</STRONG>&nbsp;function to calculate the number of years since the value in Date field. You can implement it while creating a new record using the app.</P><P><STRONG><U>Task1: </U></STRONG><STRONG>Create a determination and implement the corresponding method.</STRONG></P><OL><LI>Define a determination in the BDEF of the CDS view.<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Define Determination" style="width: 956px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/380373i6C6937570AEFC788/image-size/large?v=v2&amp;px=999" role="button" title="Define Determination.jpg" alt="Define Determination" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Define Determination</span></span></LI><LI>Now you can notice a small icon to the left of the determination definition. Click on it to create the implementation method for adding determination logic in the local handler class&nbsp;of the behavior pool of your entity. Save and activate the changes.<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Implement Determination" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/380375i93CA4B6E534F8C1D/image-size/large?v=v2&amp;px=999" role="button" title="Implement Determination Method.jpg" alt="Implement Determination" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Implement Determination</span></span>For additional information on Determinations and its syntax and use you can refer the BDEF ‘/DMO/R_Travel_D’. Alternatively you can also refer <A href="https://github.com/SAP-samples/abap-platform-rap100/blob/main/exercises/ex04" target="_blank" rel="noopener nofollow noreferrer">https://github.com/SAP-samples/abap-platform-rap100/blob/main/exercises/ex04</A></LI></OL><P><STRONG><U>Task2:</U> Enhance determination with Joule Code Prediction Capability</STRONG></P><P>Use Joule's Predictive Code Completion feature to complete your code by providing simple prompts for each step in the logic.</P><P>Here please note that we should use the Toggle option to disable / enable&nbsp;Joule Code Prediction Capability by pressing&nbsp;<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="sheenamk_0-1772735109647.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/380379iD9968BF55E6106DD/image-size/medium?v=v2&amp;px=400" role="button" title="sheenamk_0-1772735109647.png" alt="sheenamk_0-1772735109647.png" /></span>&nbsp;button in the toolbar.</P><P><EM><FONT color="#000000">Hint: Disable the&nbsp;Joule Code Prediction Capability if you want to give prompts for new steps / once finished to stop Automatic Code Prediction.</FONT></EM></P><P><FONT color="#FF0000"><SPAN>Note:- The logic and examples are mentioned just for your reference and to make the purpose of the challenge easy to understand. Please feel free to use your own logic and dataset.</SPAN></FONT></P><P><FONT color="#FF0000"><SPAN><FONT color="#000000">To know how to use&nbsp;</FONT></SPAN></FONT>Predictive Code Completion f<SPAN>ollow this&nbsp;</SPAN><A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/video-tutorials-for-predictive-code-completion?locale=en-US" target="_self" rel="noreferrer noopener">tutorial</A></P><P>Please note that the challenge will remain open for another week for anyone who is running late.&nbsp;</P><P>Before we close for this year we would like to thank everyone who participated. We hope all of you enjoyed the challenge. Let us continue to explore how&nbsp;<SPAN class="">SAP Joule for developers, ABAP AI capabilities</SPAN><SPAN>&nbsp;can support us with our day-to-day tasks when working with ABAP code, to increase our efficiency and to lower total cost of development.</SPAN></P><P><SPAN>Happy Jouling!!!</SPAN></P><P>&nbsp;</P> 2026-03-23T05:30:00.019000+01:00 https://community.sap.com/t5/technology-blog-posts-by-members/rap-factory-action-to-copy-billing-header-and-its-item-s-using-create-by/ba-p/14356589 RAP: Factory Action to copy Billing Header and its Item(s) using Create by association 2026-03-25T10:31:08.744000+01:00 SinghMohit https://community.sap.com/t5/user/viewprofilepage/user-id/1892782 <P>In this blog, I am going to explain how we can use <STRONG>create by association</STRONG> with <STRONG>factory action</STRONG> in SAP RAP environment for complex use case like <EM>copying duplicate billing header with its associated child entities</EM>.</P><P>Let's understand what action in RAP is, and what is factory action first.</P><P>If you want to perform any operation other than those four basic operations (CRUD), we can use action keyword in RAP. It helps us to do custom action like approve billing doc or change any field value like status.</P><P>We have three types of actions in RAP:</P><OL><LI>Instance Action: we need to select a record to perform action.</LI><LI>Static Actions: that are <STRONG>not tied to a specific instance</STRONG>.</LI><LI>Factory Actions: used for creating the copy of already existing instance. We will see this more in details.</LI></OL><P><STRONG>Create by Association:&nbsp;</STRONG>In scenario where we cannot create child entity as it is depend on header, we need to use create by association. Used to create deep entity.</P><P>So, let's start with the steps to generate our basic application. Please have a look.</P><P>1. My header table look like this:&nbsp;<span class="lia-unicode-emoji" title=":backhand_index_pointing_down:">👇</span></P><pre class="lia-code-sample language-abap"><code>@EndUserText.label : 'Billing Header' @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE @AbapCatalog.tableCategory : #TRANSPARENT @AbapCatalog.deliveryClass : #A @AbapCatalog.dataMaintenance : #RESTRICTED define table ztb_billheader { key client : abap.clnt not null; key bill_id : abap.numc(10) not null; bill_type : abap.char(4); bill_date : abap.dats; customer_id : kunnr; @Semantics.amount.currencyCode : 'ztb_billheader.currency' net_amount : abap.curr(15,2); currency : waers; sales_org : vkorg; createdby : syuname; createdat : timestamp; lastchangedby : syuname; lastchangedat : timestamp; locallastchangedat : timestamp; status : abap.char(1); statustext : abap.char(10); }</code></pre><P>I am not using managed numbering here as I want custom Bill Id.</P><P>2. My Item table look like this:&nbsp;<span class="lia-unicode-emoji" title=":backhand_index_pointing_down:">👇</span></P><pre class="lia-code-sample language-abap"><code>@EndUserText.label : 'Billing Item' @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE @AbapCatalog.tableCategory : #TRANSPARENT @AbapCatalog.deliveryClass : #A @AbapCatalog.dataMaintenance : #RESTRICTED define table ztb_billitem { key client : abap.clnt not null; key bill_id : abap.char(10) not null; key item_no : abap.numc(6) not null; material_id : matnr; description : abap.char(40); @Semantics.quantity.unitOfMeasure : 'ztb_billitem.uom' quantity : abap.quan(13,3); @Semantics.amount.currencyCode : 'ztb_billitem.currency' item_amount : abap.curr(15,2); currency : waers; uom : meins; createdby : syuname; createdat : timestamp; lastchangedby : syuname; lastchangedat : timestamp; locallastchangedat : timestamp; }</code></pre><P>3. I have created interface view on top of header table: You can skip that also. It looks like this:&nbsp;<span class="lia-unicode-emoji" title=":backhand_index_pointing_down:">👇</span></P><pre class="lia-code-sample language-abap"><code>@AbapCatalog.viewEnhancementCategory: [#NONE] @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Interface View for Bill header' @Metadata.ignorePropagatedAnnotations: true define view entity ZI_BillHeader as select from ztb_billheader { key bill_id as BillId, bill_type as BillType, bill_date as BillDate, customer_id as CustomerId, @Semantics.amount.currencyCode: 'Currency' net_amount as NetAmount, currency as Currency, sales_org as SalesOrg, createdby as Createdby, createdat as Createdat, lastchangedby as Lastchangedby, lastchangedat as Lastchangedat, locallastchangedat as Locallastchangedat, status as status, statustext as StatusText }</code></pre><P>4. I have created root view on top of header interface view:&nbsp;<span class="lia-unicode-emoji" title=":backhand_index_pointing_down:">👇</span></P><pre class="lia-code-sample language-abap"><code>@AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Root View Bill Header' @Metadata.ignorePropagatedAnnotations: true define root view entity ZR_BillHeader as select from ZI_BillHeader composition[0..*] of ZI_BillItem as _Item { key BillId, BillType, BillDate, CustomerId, @Semantics.amount.currencyCode: 'Currency' NetAmount, Currency, SalesOrg, Createdby, Createdat, Lastchangedby, Lastchangedat, Locallastchangedat, status, StatusText, _Item // Make association public }</code></pre><P>5. I have created interface view on top of item table:&nbsp;<span class="lia-unicode-emoji" title=":backhand_index_pointing_down:">👇</span></P><pre class="lia-code-sample language-abap"><code>@AbapCatalog.viewEnhancementCategory: [#NONE] @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Interface View for Bill Item' @Metadata.ignorePropagatedAnnotations: true define view entity ZI_BillItem as select from ztb_billitem association to parent ZR_BillHeader as _header on $projection.BillId = _header.BillId { key bill_id as BillId, key item_no as ItemNo, material_id as MaterialId, description as Description, @Semantics.quantity.unitOfMeasure: 'Uom' quantity as Quantity, @Semantics.amount.currencyCode: 'Currency' item_amount as ItemAmount, currency as Currency, uom as Uom, createdby as Createdby, createdat as Createdat, lastchangedby as Lastchangedby, lastchangedat as Lastchangedat, locallastchangedat as Locallastchangedat, _header }</code></pre><P>6. Created projection view on top of root view:&nbsp;<span class="lia-unicode-emoji" title=":backhand_index_pointing_down:">👇</span></P><pre class="lia-code-sample language-abap"><code>@AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Projection View Bill Header' @Metadata.ignorePropagatedAnnotations: true @Metadata.allowExtensions: true define root view entity ZP_BillHeader provider contract transactional_query as projection on ZR_BillHeader { key BillId, BillType, BillDate, CustomerId, @Semantics.amount.currencyCode: 'Currency' NetAmount, Currency, SalesOrg, Createdby, Createdat, Lastchangedby, Lastchangedat, Locallastchangedat, @ObjectModel.text.element: ['StatusText'] status, StatusText, /* Associations */ _Item : redirected to composition child ZP_BillItem }</code></pre><P>7. Similarly created projection view for item entity:&nbsp;<span class="lia-unicode-emoji" title=":backhand_index_pointing_down:">👇</span></P><pre class="lia-code-sample language-abap"><code>@AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Projection View Bill Item' @Metadata.ignorePropagatedAnnotations: true @Metadata.allowExtensions: true define view entity ZP_BillItem as projection on ZI_BillItem { key BillId, key ItemNo, MaterialId, Description, @Semantics.quantity.unitOfMeasure: 'Uom' Quantity, @Semantics.amount.currencyCode: 'Currency' ItemAmount, Currency, Uom, Createdby, Createdat, Lastchangedby, Lastchangedat, Locallastchangedat, /* Associations */ _header : redirected to parent ZP_BillHeader }</code></pre><P>8. My metadata looks like this:&nbsp;<span class="lia-unicode-emoji" title=":backhand_index_pointing_down:">👇</span> (Please make sure I haven't given labels for each field, so in UI for few field it will missing. My core agenda is to elaborate factory action)&nbsp;</P><P>Header:&nbsp;</P><pre class="lia-code-sample language-abap"><code>@Metadata.layer: #CORE @UI.headerInfo:{ typeName: 'Billing Document', typeNamePlural: 'Billing Documents', title: { type: #STANDARD, label: 'Biiling Document', value: 'BillId' }} annotate entity ZP_BillHeader with { @UI.facet: [{ //id: 'BillDocHeader', label: 'Billing header', position: 10, purpose: #STANDARD, type: #IDENTIFICATION_REFERENCE }, { //id: 'BillDocItem', label: 'Bill Item', position: 20, purpose: #STANDARD, type: #LINEITEM_REFERENCE, targetElement: '_Item' }] @UI.lineItem: [{ position:10 }, { position: 10, type: #FOR_ACTION, dataAction: 'ApproveBill', label: 'Approve Bill' }, { position: 20, type: #FOR_ACTION, dataAction: 'CopyBilldoc', label: 'Copy Bill' }] @UI.selectionField: [{position: 1 }] @UI.identification: [{ position: 1 }] BillId; @UI.lineItem: [{ position:20 }] @UI.identification: [{ position: 2 }] BillType; @UI.lineItem: [{ position:30 }] BillDate; @UI.lineItem: [{ position:40 }] @UI.identification: [{ position: 3 }] CustomerId; @UI.lineItem: [{ position:50 }] @UI.identification: [{ position: 4 }] NetAmount; @UI.lineItem: [{ position:60 }] @UI.identification: [{ position: 5 }] Currency; @UI.lineItem: [{ position:70 }] @UI.identification: [{ position: 6 }] SalesOrg; @UI.lineItem: [{ position:80 }] @UI.identification: [{ position: 7 }] @UI.textArrangement: #TEXT_ONLY status; }</code></pre><P>Item:&nbsp;</P><pre class="lia-code-sample language-abap"><code>@Metadata.layer: #CORE annotate entity ZP_BillItem with { <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1445379">@ui</a>.facet: [ { id: 'BillDocItem', purpose: #STANDARD, type: #IDENTIFICATION_REFERENCE, label: 'Billing Doc Item', position: 10 }] @UI.lineItem: [{ position:10 }] @UI.identification: [{ position: 1 }] BillId; @UI.lineItem: [{ position:20 }] @UI.identification: [{ position: 1 }] ItemNo; @UI.lineItem: [{ position:30 }] @UI.identification: [{ position: 1 }] MaterialId; @UI.lineItem: [{ position:40 }] Description; @UI.lineItem: [{ position:50 }] Quantity; @UI.lineItem: [{ position:70 }] ItemAmount; @UI.lineItem: [{ position:80 }] Currency; @UI.lineItem: [{ position:60 }] Uom; @UI.lineItem: [{ position:90 }] Createdby; @UI.lineItem: [{ position:100 }] Createdat; @UI.lineItem: [{ position:110 }] /* Associations */ _header; }</code></pre><P>Now we have basic structure ready !!! Main steps for our topic start from here.</P><P>9. Create behavior definition on top of root entity. Just right click on the root view entity and select new behavior definition as shown below&nbsp;<span class="lia-unicode-emoji" title=":backhand_index_pointing_down:">👇</span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="SinghMohit_0-1774326723292.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388127iE8EB6E4A780DEAE1/image-size/medium?v=v2&amp;px=400" role="button" title="SinghMohit_0-1774326723292.png" alt="SinghMohit_0-1774326723292.png" /></span></P><P>Once behavior definition is generated, use quick fix to implement behavior class.&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="SinghMohit_1-1774326927563.png" style="width: 576px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388128iB3A52BE7047C4E30/image-dimensions/576x59?v=v2" width="576" height="59" role="button" title="SinghMohit_1-1774326927563.png" alt="SinghMohit_1-1774326927563.png" /></span></P><P>10. Now add below syntax in behavior definition:</P><pre class="lia-code-sample language-abap"><code> factory action CopyBilldoc [1];</code></pre><P>The whole behavior definition looks like this:&nbsp;</P><pre class="lia-code-sample language-abap"><code>managed implementation in class zbp_r_billheader unique; strict ( 2 ); with draft; define behavior for ZR_BillHeader //alias &lt;alias_name&gt; persistent table ztb_billheader draft table ztb_billhdr_drf lock master total etag Lastchangedat authorization master ( instance, global ) etag master Locallastchangedat { create; update; delete; draft action Edit; draft action Resume; draft determine action Prepare; draft action Activate optimized; draft action Discard; field ( readonly : update, mandatory : create ) BillId; action ( features : instance ) ApproveBill result [1] $self; factory action CopyBilldoc [1]; side effects { action CopyBilldoc affects $self; } association _Item { create; with draft; } mapping for ztb_billheader { BillId = bill_id; BillType = bill_type; BillDate = bill_date; CustomerId = customer_id; NetAmount = net_amount; Currency = currency; SalesOrg = sales_org; CreatedBy = createdby; CreateDat = createdat; LastChangedBy = lastchangedby; LastChangeDat = lastchangedat; LocalLastChangeDat = locallastchangedat; status = status; StatusText = statustext; } } define behavior for ZI_BillItem //alias &lt;alias_name&gt; persistent table ztb_billitem draft table ztb_billitem_drf lock dependent by _header authorization dependent by _header //etag master &lt;field_name&gt; { update; delete; field ( readonly : update, mandatory : create ) BillId, ItemNo; association _header { with draft; } mapping for ztb_billitem { BillId = bill_id; ItemNo = item_no; MaterialId = material_id; Description = description; Quantity = quantity; ItemAmount = item_amount; Currency = currency; Uom = uom; CreatedBy = createdby; CreateDat = createdat; LastChangedBy = lastchangedby; LastChangeDat = lastchangedat; LocalLastChangeDat = locallastchangedat; } }</code></pre><P>Here, I have added extra things like draft, custom action and side effects. But for now, just focus on the line number 24.</P><P>11. Activate and use quick fix to generate this method in behavior class.&nbsp;</P><P>12. Use below code inside the generated factory action method.&nbsp;<span class="lia-unicode-emoji" title=":backhand_index_pointing_down:">👇</span></P><pre class="lia-code-sample language-abap"><code>METHOD CopyBilldoc. " Declaration of internal tables. DATA: lt_bill TYPE TABLE FOR CREATE ZR_BillHeader\\ZR_BillHeader, lt_billitem TYPE TABLE FOR CREATE ZR_BillHeader\_item. DATA: lv_billId TYPE c LENGTH 10. " Reading highest existing bill id and incrementing it by 1 to use as new bill id SELECT BillId FROM ZR_BillHeader ORDER BY BillId DESCENDING INTO _billid UP TO 1 ROWS. ENDSELECT. lv_billId = lv_billId + 1. " Read by association READ ENTITIES OF ZR_BillHeader IN LOCAL MODE ENTITY ZR_BillHeader ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(lt_data1) ENTITY ZR_BillHeader BY \_item ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(lt_data2) FAILED failed. " Appending to create a new structure LOOP AT lt_data1 ASSIGNING FIELD-SYMBOL(&lt;ls_data1&gt;). APPEND VALUE #( %cid = keys[ KEY entity %key = &lt;ls_data1&gt;-%key ]-%cid "%is_draft = keys[ KEY entity %key = &lt;ls_data1&gt;-%key ]-%param-%is_draft %data = CORRESPONDING #( &lt;ls_data1&gt; EXCEPT BillId ) ) TO lt_bill ASSIGNING FIELD-SYMBOL(&lt;new_bill_doc&gt;). &lt;new_bill_doc&gt;-BillId = CONV #( lv_billId ). &lt;new_bill_doc&gt;-BillDate = cl_abap_context_info=&gt;get_system_date( ). LOOP AT lt_data2 INTO DATA(ls_data2). APPEND VALUE #( %cid_ref = &lt;new_bill_doc&gt;-%cid "BillId = &lt;new_bill_doc&gt;-BillId %target = VALUE #( ( %cid = &lt;new_bill_doc&gt;-%cid BillId = &lt;new_bill_doc&gt;-BillId MaterialId = ls_data2-MaterialId ItemNo = ls_data2-ItemNo ) ) ) TO lt_billitem ASSIGNING FIELD-SYMBOL(&lt;new_bill_item&gt;). ENDLOOP. ENDLOOP. "Create BO instance by copy. MODIFY ENTITIES OF ZR_BillHeader IN LOCAL MODE ENTITY ZR_BillHeader CREATE FIELDS ( BillId BillDate BillType Currency CustomerId NetAmount SalesOrg ) WITH VALUE #( ( %cid = &lt;new_bill_doc&gt;-%cid BillId = &lt;new_bill_doc&gt;-BillId BillDate = &lt;new_bill_doc&gt;-BillDate Currency = &lt;new_bill_doc&gt;-Currency CustomerId = &lt;new_bill_doc&gt;-CustomerId NetAmount = &lt;new_bill_doc&gt;-NetAmount SalesOrg = &lt;new_bill_doc&gt;-SalesOrg ) ) CREATE BY \_item FIELDS ( ItemNo MaterialId ) WITH VALUE #( ( %cid_ref = &lt;new_bill_doc&gt;-%cid %target = VALUE #( FOR i IN lt_billitem FOR j IN i-%target ( %cid = j-ItemNo ItemNo = j-ItemNo MaterialId = j-MaterialId ) ) ) ) MAPPED DATA(mapped_create). " Set values to front end. mapped-ZR_BillHeader = mapped_create-ZR_BillHeader. ENDMETHOD.</code></pre><P>The whole my behavior class looks like this:&nbsp;<span class="lia-unicode-emoji" title=":backhand_index_pointing_down:">👇</span></P><pre class="lia-code-sample language-abap"><code>CLASS lhc_ZR_BillHeader DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION IMPORTING keys REQUEST requested_authorizations FOR ZR_BillHeader RESULT result. METHODS get_global_authorizations FOR GLOBAL AUTHORIZATION IMPORTING REQUEST requested_authorizations FOR ZR_BillHeader RESULT result. METHODS ApproveBill FOR MODIFY IMPORTING keys FOR ACTION ZR_BillHeader~ApproveBill RESULT result. METHODS get_instance_features FOR INSTANCE FEATURES IMPORTING keys REQUEST requested_features FOR ZR_BillHeader RESULT result. METHODS copybilldoc FOR MODIFY IMPORTING keys FOR ACTION zr_billheader~copybilldoc. ENDCLASS. CLASS lhc_ZR_BillHeader IMPLEMENTATION. METHOD get_instance_authorizations. ENDMETHOD. METHOD get_global_authorizations. ENDMETHOD. METHOD ApproveBill. MODIFY ENTITIES OF ZR_BillHeader IN LOCAL MODE ENTITY ZR_BillHeader UPDATE FROM VALUE #( FOR key IN keys ( %tky = key-%tky status = 'A' " Approved StatusText = 'Approved' %control-status = if_abap_behv=&gt;mk-on %control-StatusText = if_abap_behv=&gt;mk-on ) ) FAILED failed REPORTED reported. "Read changed data for action result READ ENTITIES OF ZR_BillHeader IN LOCAL MODE ENTITY ZR_BillHeader ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(billheaders). result = VALUE #( FOR billheader IN billheaders ( %tky = billheader-%tky %param = billheader ) ). ENDMETHOD. METHOD get_instance_features. READ ENTITIES OF ZR_BillHeader IN LOCAL MODE ENTITY ZR_BillHeader FIELDS ( BillId status ) WITH CORRESPONDING #( keys ) RESULT DATA(BillHeaders) FAILED failed. result = VALUE #( FOR BillHeader IN BillHeaders ( %key = BillHeader-%key %features-%action-ApproveBill = COND #( WHEN BillHeader-status = 'A' THEN if_abap_behv=&gt;fc-o-disabled ELSE if_abap_behv=&gt;fc-o-enabled ) ) ). ENDMETHOD. METHOD CopyBilldoc. " Copy records assigned to internal table. DATA: lt_bill TYPE TABLE FOR CREATE ZR_BillHeader\\ZR_BillHeader, lt_billitem TYPE TABLE FOR CREATE ZR_BillHeader\_item. DATA: lv_billId TYPE c LENGTH 10. SELECT BillId FROM ZR_BillHeader ORDER BY BillId DESCENDING INTO _billid UP TO 1 ROWS. ENDSELECT. lv_billId = lv_billId + 1. READ ENTITIES OF ZR_BillHeader IN LOCAL MODE ENTITY ZR_BillHeader ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(lt_data1) ENTITY ZR_BillHeader BY \_item ALL FIELDS WITH CORRESPONDING #( keys ) RESULT DATA(lt_data2) FAILED failed. LOOP AT lt_data1 ASSIGNING FIELD-SYMBOL(&lt;ls_data1&gt;). APPEND VALUE #( %cid = keys[ KEY entity %key = &lt;ls_data1&gt;-%key ]-%cid "%is_draft = keys[ KEY entity %key = &lt;ls_data1&gt;-%key ]-%param-%is_draft %data = CORRESPONDING #( &lt;ls_data1&gt; EXCEPT BillId ) ) TO lt_bill ASSIGNING FIELD-SYMBOL(&lt;new_bill_doc&gt;). &lt;new_bill_doc&gt;-BillId = CONV #( lv_billId ). &lt;new_bill_doc&gt;-BillDate = cl_abap_context_info=&gt;get_system_date( ). LOOP AT lt_data2 INTO DATA(ls_data2). APPEND VALUE #( %cid_ref = &lt;new_bill_doc&gt;-%cid "BillId = &lt;new_bill_doc&gt;-BillId %target = VALUE #( ( %cid = &lt;new_bill_doc&gt;-%cid BillId = &lt;new_bill_doc&gt;-BillId MaterialId = ls_data2-MaterialId ItemNo = ls_data2-ItemNo ) ) ) TO lt_billitem ASSIGNING FIELD-SYMBOL(&lt;new_bill_item&gt;). ENDLOOP. ENDLOOP. "Create BO instance by copy. MODIFY ENTITIES OF ZR_BillHeader IN LOCAL MODE ENTITY ZR_BillHeader CREATE FIELDS ( BillId BillDate BillType Currency CustomerId NetAmount SalesOrg ) WITH VALUE #( ( %cid = &lt;new_bill_doc&gt;-%cid BillId = &lt;new_bill_doc&gt;-BillId BillDate = &lt;new_bill_doc&gt;-BillDate Currency = &lt;new_bill_doc&gt;-Currency CustomerId = &lt;new_bill_doc&gt;-CustomerId NetAmount = &lt;new_bill_doc&gt;-NetAmount SalesOrg = &lt;new_bill_doc&gt;-SalesOrg ) ) CREATE BY \_item FIELDS ( ItemNo MaterialId ) WITH VALUE #( ( %cid_ref = &lt;new_bill_doc&gt;-%cid %target = VALUE #( FOR i IN lt_billitem FOR j IN i-%target ( %cid = j-ItemNo ItemNo = j-ItemNo MaterialId = j-MaterialId ) ) ) ) MAPPED DATA(mapped_create). " Set values to front end. mapped-ZR_BillHeader = mapped_create-ZR_BillHeader. ENDMETHOD. ENDCLASS.</code></pre><P>13. Create behavior projection on top of root projection view. It will look like this&nbsp;<span class="lia-unicode-emoji" title=":backhand_index_pointing_down:">👇</span></P><pre class="lia-code-sample language-abap"><code>projection; strict ( 2 ); use draft; define behavior for ZP_BillHeader //alias &lt;alias_name&gt; { use create; use update; use delete; use action Edit; use action Activate; use action Discard; use action Resume; use action Prepare; use action ApproveBill; use action CopyBilldoc; use association _Item { create; with draft;} } define behavior for ZP_BillItem //alias &lt;alias_name&gt; { use update; use delete; use association _header { with draft; } }</code></pre><P>14. Now create the service definition and expose both header and item projection:&nbsp;</P><pre class="lia-code-sample language-abap"><code>@EndUserText.label: 'Service Definition for Billing Doc' define service ZSD_BillingDocument { expose ZP_BillHeader as BillingHeader; expose ZP_BillItem as BillingItem; }</code></pre><P>15. On top of service definition, create a service binding. I have use Odata V4 as I am using draft functionality.&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="SinghMohit_2-1774328092749.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388129i3F002C5161BFBF94/image-size/medium?v=v2&amp;px=400" role="button" title="SinghMohit_2-1774328092749.png" alt="SinghMohit_2-1774328092749.png" /></span></P><P>16. Finally, it's a result time. Have a first look of our application.&nbsp;<span class="lia-unicode-emoji" title=":backhand_index_pointing_down:">👇</span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="SinghMohit_3-1774328288719.png" style="width: 633px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388130i323F6AD395B25E2C/image-dimensions/633x304?v=v2" width="633" height="304" role="button" title="SinghMohit_3-1774328288719.png" alt="SinghMohit_3-1774328288719.png" /></span></P><P>17. Now select any record and click on copyBill. I am selecting second record.&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="SinghMohit_4-1774328376670.png" style="width: 627px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388131iD0F0B064DD1FA3F6/image-dimensions/627x315?v=v2" width="627" height="315" role="button" title="SinghMohit_4-1774328376670.png" alt="SinghMohit_4-1774328376670.png" /></span></P><P>18. Once I clicked on copyBill, We can see a new BillId is generated with same line items as of source record.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="SinghMohit_5-1774328485372.png" style="width: 637px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/388132i402D372E50CFD5C7/image-dimensions/637x297?v=v2" width="637" height="297" role="button" title="SinghMohit_5-1774328485372.png" alt="SinghMohit_5-1774328485372.png" /></span></P><P><STRONG>Conclusion:&nbsp;</STRONG>So, we have come to the end of our blog. We have seen how we can implement an use case related to factory action. I want to summarise important steps again required to implement factory action:&nbsp;</P><OL><LI>Declare factory action in behavior definition and activate it.</LI><LI>Use quick fix to generate the method in implementation class.&nbsp;</LI><LI>Use Read by association to read both header and child entity.</LI><LI>Append the new structure.</LI><LI>Create new duplicate BO entry by using create by association.</LI></OL><P>Thank You for reading my blog. Do comment if you have any doubt or if you know any better way to do this. Good Bye&nbsp;<span class="lia-unicode-emoji" title=":waving_hand:">👋</span></P> 2026-03-25T10:31:08.744000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/our-2026-roadmap-for-joule-for-developers-abap-ai-capabilities/ba-p/14360358 Our 2026 Roadmap for Joule for Developers ABAP AI capabilities 2026-03-28T20:13:48.908000+01:00 JanMatthes https://community.sap.com/t5/user/viewprofilepage/user-id/194386 <P data-unlink="true"><A title="ABAP AI Capabilities" href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/joule-for-developers-abap-ai-capabilities-f14ebffef77b41bfb0746c33dcb70e84" target="_blank" rel="noopener noreferrer"><BR /><span class="lia-inline-image-display-wrapper lia-image-align-left" image-alt="J4D_Agentic.png" style="width: 200px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/390078iDD4D1E72EFCEDA09/image-size/small?v=v2&amp;px=200" role="button" title="J4D_Agentic.png" alt="J4D_Agentic.png" /></span></A><A href="https://www.sap.com/events/sapphire/orlando/flow/sap/so26/catalog/page/catalog?search=ABAP&amp;tab.sessionplanned=1692641568884001cZ9d" target="_blank" rel="noopener noreferrer"><STRONG>Sapphire 2026 </STRONG>is approaching quickly and as usual it will bring lots of new announcements.</A> So now is the right point in time to recap what has been announced already until Q2/2026 and prepare for the <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/joule-for-developers-abap-ai-sapphire-and-asug-2026-sessions/ba-p/14365782" target="_blank">ABAP AI sessions</A>.</P><P class="lia-indent-padding-left-30px" data-unlink="true" style="padding-left : 30px;">The <STRONG>ABAP Platform&nbsp;AI</STRONG> (covering both SAP BTP ABAP Environment and SAP S/4HANA) transitions from a set of independent AI skills to full-scale <STRONG>Agentic AI</STRONG>. <SPAN class="">The roadmap focuses heavily on developer productivity via Joule and the modernization of ABAP development tools. The key benefits for customers and partners of the&nbsp;<STRONG>roadmap until Q2/2026 are:</STRONG></SPAN></P><P data-unlink="true">&nbsp;</P><OL><LI><SPAN class="">ABAP </SPAN><SPAN class="">development&nbsp;</SPAN><SPAN class="">tools</SPAN>&nbsp;<SPAN class="">in</SPAN><STRONG><SPAN class="">&nbsp;VS Code with ABAP MCP Server.</SPAN></STRONG></LI><LI><SPAN class="">ABAP AI </SPAN><SPAN class="">f</SPAN><SPAN class="">or lower releases of </SPAN><STRONG><SPAN class="">SAP S/4HANA Cloud Private Edition (i.e. 2021, 2022, 2023 and 2025).</SPAN></STRONG></LI><LI><STRONG><SPAN class="">Simplified customer on-boarding of ABAP AI&nbsp;</SPAN></STRONG><SPAN class="">via SAP for Me and Central Business Configuration</SPAN><STRONG><SPAN class="">.</SPAN></STRONG></LI><LI><SPAN class=""><STRONG>Faster innovation with Side-by-Side consumption of SAP and 3rd party Agentic IDEs and LLMs</STRONG><BR />(e.g. Microsoft, Amazon, IBM, OpenAI, Anthropic, Google, Mistral…)</SPAN></LI></OL><DIV class="">&nbsp;</DIV><DIV class=""><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="J4D_Agentic_sbs.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/390119i0AFD64FE139637CA/image-size/large?v=v2&amp;px=999" role="button" title="J4D_Agentic_sbs.png" alt="J4D_Agentic_sbs.png" /></span></DIV><DIV class=""><P><SPAN class="">The biggest shift in 2026 will be the <STRONG>move toward Agentic AI</STRONG>, where the existing ABAP AI skills doesn't just explain, complete or generate code (e.g. RAP, CDS, Tests) <STRONG>independently but acts as an autonomous collaborator</STRONG>.&nbsp;</SPAN><SPAN class="">This includes built-in <STRONG>ABAP MCP (Model Context Protocol) server.</STRONG> The introduction of VS Code as IDE can only be a start as the depth and breath of Eclipse which we achieved in so many years cannot be reached with one or two steps in VS Code. It'll be a journey which starts with first providing&nbsp;End-to-end UI services development with agents.</SPAN></P><P><SPAN class="">The new ABAP AI side-by-side architecture is designed to provide a scalable and future‑proof foundation for <STRONG>ABAP AI capabilities across heterogeneous SAP landscapes</STRONG>. It enables customers to consume ABAP AI services side‑by‑side, independent of the underlying S/4HANA release, ensuring access even <STRONG>for lower‑release Private Edition systems</STRONG>.&nbsp;</SPAN></P><P><SPAN class="">A core benefit of the architecture is also its simplified enablement model through SAP for Me and Central Business Configuration, reducing on-boarding effort and ensuring consistent lifecycle management across environments.&nbsp;<BR />In addition, the architecture allows us to accelerate innovation speed by allowing to <STRONG>leverage SAP‑provided ABAP AI models alongside leading third‑party LLMs</STRONG> (e.g., Microsoft, Amazon, IBM, OpenAI, Anthropic, Google, Mistral) <STRONG>more independently from releases</STRONG>. This flexibility ensures rapid adoption of new capabilities without dependency on individual release cycles.</SPAN></P><P><SPAN class="">If you missed the <STRONG>highlights we delivered in Q1/2026</STRONG> have a look into what <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/custom-code-migration-to-sap-s-4hana-powered-by-sap-joule-for-developers/ba-p/14329094" target="_blank">Olga Dolinskaja shared about ABAP AI ATC finding explain and custom code explain and proposals</A>. Although this will be a focus also for our future roadmap we will also not stop investing into AI app generators like the&nbsp;<A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/cds-analytical-model-generation-powered-by-ai" target="_blank" rel="noopener noreferrer">Embedded Analytics model generator</A>.&nbsp;</SPAN></P></DIV><DIV class="">&nbsp;</DIV><DIV class=""><STRONG>Here you can learn more:</STRONG></DIV><DIV class=""><div class="video-embed-center video-embed"><iframe class="embedly-embed" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FaU3Eu2SlvxE%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DaU3Eu2SlvxE&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FaU3Eu2SlvxE%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="400" height="225" scrolling="no" title="ABAP AI Roadmap, CAP Jan 2026 Release, Brazil CodeJams, CAP Roundtable, DYK #3 | SAP Developer News" frameborder="0" allow="autoplay; fullscreen; encrypted-media; picture-in-picture;" allowfullscreen="true"></iframe></div></DIV><OL><LI><SPAN class=""><A class="" href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-joule-for-developers-expands-to-private-cloud-accelerating-abap/ba-p/14237958" target="_blank">SAP Joule for Developers (J4D) Expands to Private Cloud: Accelerating ABAP Innovation and Transformation </A></SPAN></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/your-2026-roadmap-to-getting-started-with-abap-ai-and-abap-1/ba-p/14312060" target="_blank"><SPAN class="">Your Roadmap for getting started with ABAP AI</SPAN></A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/abap-ai-revolution-accelerates-the-abap-developer-who-built-enterprise-apps/ba-p/14216073" target="_blank"><SPAN class="">ABAP AI Revolution Accelerates: The ABAP Developer Who Built Enterprise Apps in Minutes </SPAN></A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/introducing-the-next-era-of-abap-development/ba-p/14260522" target="_blank"><SPAN class="">Joule for Developers and ABAP AI capabilities are coming to SAP S/4HANA Private Edition 2021, 2022, and 2023</SPAN></A></LI><LI><SPAN class="">Public Roadmap: <A href="https://help.sap.com/docs/abap-cross-product/roadmap-info/genai" target="_blank" rel="noopener noreferrer">SAP Help</A> / <A href="https://roadmaps.sap.com/board?PRODUCT=73554900100800001562&amp;PRODUCT=73555000100800001164&amp;range=CURRENT-LAST" target="_blank" rel="noopener noreferrer">SAP Roadmap Explorer</A></SPAN></LI><LI><SPAN class="">Help &amp; Guides</SPAN><OL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/sap-joule-for-developers-abap-ai-capabilities-for-sap-s-4hana-cloud-private/ba-p/14236954" target="_blank"><SPAN class="">Step-by-step guide how to activate SAP Joule for Developers, ABAP AI capabilities for your SAP S/4HANA Cloud Private Edition</SPAN></A></LI><LI><SPAN class=""><SPAN><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/joule-for-developers-with-sap-s-4hana-public-cloud-edition-setup-guide/ba-p/14209989" target="_blank">Joule for Developers (J4D) for S/4HANA Public Cloud Setup Guide</A></SPAN></SPAN></LI><LI><A href="https://discovery-center.cloud.sap/search/abap%20ai" target="_blank" rel="noopener nofollow noreferrer"><SPAN class=""><SPAN>SAP ABAP AI Discovery Center</SPAN></SPAN></A></LI><LI><SPAN class=""><SPAN><A class="" href="https://discovery-center.cloud.sap/search/Free-tier" target="_blank" rel="noopener nofollow noreferrer">SAP BTP Discovery Center (Free Tier Services)</A></SPAN></SPAN></LI><LI><SPAN class=""><SPAN><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/custom-code-migration-to-sap-s-4hana-powered-by-sap-joule-for-developers/ba-p/14329094" target="_blank">Custom code migration to SAP S/4HANA powered by SAP Joule for Developers, ABAP AI capabilities</A> </SPAN></SPAN></LI><LI><A href="http://www.youtube.com/playlist?list=PL6RpkC85SLQAt9lvPw0gF4E3nwbJD0EUe" target="_blank" rel="noopener nofollow noreferrer"><SPAN class=""><SPAN>YouTube playlist for Joule for Developers (J4D)</SPAN></SPAN></A></LI><LI><A href="https://help.sap.com/docs/abap-ai" target="_blank" rel="noopener noreferrer"><SPAN class=""><SPAN>Joule for Developers Help (J4D)</SPAN></SPAN></A></LI><LI><A href="https://github.com/SAP-samples/abap-platform-rap120" target="_blank" rel="noopener nofollow noreferrer">Build SAP Fiori Apps with ABAP Cloud and SAP Joule for developers (RAP120)</A>&nbsp;</LI><LI><A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/joule-for-developers-abap-ai-capabilities-f14ebffef77b41bfb0746c33dcb70e84" target="_blank" rel="noopener noreferrer"><SPAN class=""><SPAN>ADT Eclipse AI Capabilities Help</SPAN></SPAN></A></LI><LI><SPAN class=""><SPAN><A class="" href="https://help.sap.com/docs/abap-ai/generative-ai-in-abap-cloud/set-up-abap-ai-sdk-powered-by-intelligent-scenario-lifecycle-management" target="_blank" rel="noopener noreferrer">ABAP AI SDK Help</A></SPAN></SPAN></LI><LI><A href="https://help.sap.com/docs/sap-ai-core/generative-ai/sap-abap-1?locale=en-US&amp;version=LATEST" target="_blank" rel="noopener noreferrer"><SPAN class="">ABAP-1 Help</SPAN></A></LI></OL></LI></OL><P data-unlink="true"><SPAN class="">More high-level insights about <A href="https://www.sap.com/sea/products/artificial-intelligence/joule-for-developers.html" target="_blank" rel="noopener noreferrer">Joule for Developers/ABAP AI</A> and <A href="https://www.sap.com/products/technology-platform/abap/environment.html" target="_blank" rel="noopener noreferrer">ABAP platform can be found&nbsp;here</A>&nbsp;. Here you find <A href="https://www.sap.com/products/artificial-intelligence/sap-abap.html" target="_blank" rel="noopener noreferrer">more on ABAP-&nbsp;1</A>,</SPAN></P> 2026-03-28T20:13:48.908000+01:00 https://community.sap.com/t5/abap-blog-posts/optional-task-use-joule-cds-unit-test-generation/ba-p/14358864 Optional Task: Use Joule CDS Unit Test Generation 2026-03-30T06:30:00.020000+02:00 Shilpa_Shankar https://community.sap.com/t5/user/viewprofilepage/user-id/141830 <P>Thank you to everyone who participated in the ABAP Developer Challenge over the past four weeks and successfully completed all four tasks focused on ABAP AI capabilities. We truly appreciate the enthusiasm and engagement shown throughout the challenge. As a follow-up, we are excited to introduce an additional bonus task.</P><P>In Week 2, you enhanced a CDS data definition by implementing simple logic. Building on that work, your next step is to create an ABAP test class to validate the logic within the CDS data definition. For this task, you will utilize another feature of Joule’s ABAP AI capabilities — <STRONG>CDS Test Generation</STRONG>.</P><P>Task:</P><UL><LI>Select the CDS data definition that you enhanced in Week 2.</LI><LI>Generate an ABAP test class using Joule’s CDS Test Generation feature.</LI><LI>Execute the test class and ensure that all generated test cases run successfully.</LI></UL><P>Please refer to the link below for detailed guidance on how to use this ABAP AI capability.</P><P><A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/use-cds-test-class-generator?locale=en-US" target="_blank" rel="noopener noreferrer">https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/use-cds-test-class-generator?locale=en-US</A></P> 2026-03-30T06:30:00.020000+02:00 https://community.sap.com/t5/technology-blog-posts-by-sap/smaller-abap-runtime-size-now-available-in-sap-btp-abap-environment/ba-p/14350033 Smaller ABAP Runtime Size Now Available in SAP BTP ABAP Environment 2026-03-31T14:40:48.302000+02:00 Burcu_Karlidag https://community.sap.com/t5/user/viewprofilepage/user-id/151005 <P>Starting <STRONG>March 31, 2026</STRONG>, SAP BTP ABAP environment introduces a new runtime sizing option: <STRONG>0.5 ABAP Compute Units (ACU)</STRONG>&nbsp;which is<SPAN class=""><STRONG>&nbsp;8 GB of runtime memory</STRONG>.</SPAN></P><P><SPAN class="">With the introduction of 0.5 ACU, customers can now operate ABAP systems at<STRONG>&nbsp;50% lower ABAP runtime cost compared to the previous minimum size of 1 ACU</STRONG>&nbsp;making it significantly more cost-efficient to run development, test, and sandbox systems.</SPAN></P><P>This enhancement allows&nbsp;SAP BTP ABAP environment to run on <STRONG>smaller runtime units,&nbsp;</STRONG>&nbsp;lowering the entry barrier for development and test systems.</P><H2 id="toc-hId-1792231301"><STRONG>What is an ABAP Compute Unit (ACU)?</STRONG></H2><P>ABAP Compute Units (ACUs) define the runtime capacity of an SAP BTP ABAP environment system. One ACU corresponds to <STRONG>16 GB of memory</STRONG> allocated to the ABAP runtime. The total runtime size determines how much capacity is available across all ABAP application servers. For more information, see the documentation on <A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/abap-compute-units" target="_self" rel="noopener noreferrer">ABAP Compute Units</A>.</P><H2 id="toc-hId-1595717796">What’s New?</H2><P>With this update&nbsp;<STRONG>SAP BTP ABAP environment</STRONG> now supports <STRONG>0.5 ABAP Compute Units (ACU)</STRONG>&nbsp;as the new minimum system configuration.</P><P>It allows to run smaller systems, enabling more granular runtime sizing compared to previous configurations. It creates an additional option to better match the actual workloads, particularly for smaller environments.</P><H2 id="toc-hId-1399204291"><STRONG>What are the Key Benefits?</STRONG></H2><UL><LI><STRONG>50% lower ABAP runtime cost</STRONG> compared to the previous minimum size (1 ACU)</LI><LI><STRONG>Improved resource utilization</STRONG> for smaller or variable workloads</LI><LI><STRONG>Lower entry barrier</STRONG> for new and existing customers</LI></UL><P>For a detailed breakdown of cost components, see my previous <A href="https://community.sap.com/t5/technology-blog-posts-by-sap/optimize-your-sap-btp-abap-environment-budget-a-detailed-cost-analysis-for/ba-p/13574333" target="_self">blog post</A> on ABAP environment cost calculation.</P><H2 id="toc-hId-1202690786"><STRONG>How to Adjust Existing Systems?</STRONG></H2><P data-unlink="true">Adjusting the ABAP runtime size (ACUs) is handled via manual scaling and <STRONG>does not lead to a system downtime</STRONG>&nbsp;. You can use the SAP BTP Cockpit to update the service instance, for example, from 1 ACU to 0,5 ACU, see the documentation on <A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/updating-abap-system" target="_self" rel="noopener noreferrer">Updating an ABAP System</A>.</P><H2 id="toc-hId-1006177281"><STRONG>What Needs to be Considered?</STRONG></H2><P>For systems with a runtime size of <STRONG>0.5 ACU</STRONG>, only one application server is used. This setup is suited for development and test, but <STRONG>not recommended for productive use</STRONG>, as it may increase the likelihood of short outages.</P><H3 id="toc-hId-938746495"><SPAN class="">Overview about typical use cases and recommend systems sizes</SPAN></H3><TABLE border="1"><TBODY><TR><TD width="409px" height="50px"><P><STRONG>Use Case</STRONG></P></TD><TD width="143px" height="50px"><P><STRONG>Size</STRONG></P></TD><TD width="198px" height="50px"><STRONG>Total Runtime Memory</STRONG></TD><TD width="178px" height="50px"><STRONG>Application Servers</STRONG></TD></TR><TR><TD width="409px" height="41px"><P>Development, test, sandbox systems for smaller projects</P></TD><TD width="143px" height="41px"><P><STRONG>0.5 ACU (new)</STRONG></P></TD><TD width="198px" height="41px">8 GB</TD><TD width="178px" height="41px">1 á 8 GB</TD></TR><TR><TD width="409px" height="57px">Development, test, sandbox systems for bigger projects;<BR />Productive systems for up to 1,000 active users per day</TD><TD width="143px" height="57px"><STRONG>1 ACU</STRONG></TD><TD width="198px" height="57px">16 GB</TD><TD width="178px" height="57px">2 á 8 GB</TD></TR><TR><TD width="409px" height="57px">Productive systems with higher concurrency or up to 100 tenants&nbsp;</TD><TD width="143px" height="57px"><STRONG>2 ACU</STRONG></TD><TD width="198px" height="57px">32 GB</TD><TD width="178px" height="57px">4 á 8 GB</TD></TR><TR><TD width="409px" height="30px">Productive systems with bigger max session size</TD><TD width="143px" height="30px"><STRONG>4 ACU</STRONG></TD><TD width="198px" height="30px">64 GB</TD><TD width="178px" height="30px">2 á 32 GB</TD></TR><TR><TD width="409px" height="57px">Productive systems with higher load in multitenant SaaS solution&nbsp;</TD><TD width="143px" height="57px"><STRONG>4 ACU</STRONG></TD><TD width="198px" height="57px">64 GB</TD><TD width="178px" height="57px">8 á 8 GB</TD></TR></TBODY></TABLE><P>&nbsp;</P><H2 id="toc-hId-613150271">Further References&nbsp;</H2><P>For more information about sizing options and configuration parameters in <STRONG>SAP BTP ABAP environment</STRONG>, see the documentation on&nbsp;<A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/creating-abap-system?version=Cloud" target="_self" rel="noopener noreferrer">Creating an ABAP System</A>.</P> 2026-03-31T14:40:48.302000+02:00 https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-members/dynamic-watermark-in-sap-s-4hana-public-cloud-output-management-a-step-by/ba-p/14362663 Dynamic Watermark in SAP S/4HANA Public Cloud Output Management: A Step-by-Step Guide 2026-04-01T09:29:57.553000+02:00 kamilmirza https://community.sap.com/t5/user/viewprofilepage/user-id/15938 <P>Recently, I got one of those requirements that sounds incredibly simple on paper but turns into an interesting technical puzzle once you work on S4HPC.</P><P>The business wanted a conditional watermark on their Purchase Order Output Form. If the PO is still navigating the approval workflow, it needs to display a massive "DRAFT" watermark across all pages. Once fully approved and released, that watermark needs to disappear completely.</P><P>The idea is straightforward: add custom logic to make the watermark conditional at both, form template level and the data source level. But as anyone who works with SAP Output Management knows, getting the Master Form and Content Form to talk to each other isn't always plug-and-play.</P><P>Here is how I did it.</P><H3 id="toc-hId-1922302982">Step 1: The Data Source Dilemma</H3><P>Since the watermark needs to appear on all pages, the logical place to put it is the master form template.</P><P>First, I checked the standard PO form data source&nbsp;<CODE>FDP_EF_PURCHASE_ORDER_SRV</CODE> to see if I could simply grab the <CODE>PurchasingProcessingStatus</CODE> and <CODE>ReleaseIsNotCompleted</CODE> fields of&nbsp;<CODE>I_PurchaseOrderAPI01</CODE> view&nbsp;to build my condition. Unsurprisingly, they weren't there.</P><P>My next thought was to extend the standard data source via the <STRONG>Custom Fields</STRONG> app. However, <CODE>FDP_EF_PURCHASE_ORDER_SRV</CODE> cannot be extended.</P><P>After some digging, I came across <A href="https://me.sap.com/notes/3525721" target="_blank" rel="noopener noreferrer"><STRONG>SAP Note 3525721</STRONG></A>, which states that custom fields <I>can</I> be used for the PO output data source with the use BAdI <CODE>MMPUR_PO_OUTPUT_HEADER_EXT</CODE>.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-left" image-alt="firefox_Ow0l1Ycr6s.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/391435iF39B877436A64219/image-size/large?v=v2&amp;px=999" role="button" title="firefox_Ow0l1Ycr6s.png" alt="firefox_Ow0l1Ycr6s.png" /></span></P><P>&nbsp;</P><H3 id="toc-hId-1725789477">Step 2: Adding the Custom Field via BAdI&nbsp;</H3><P>First, I went to the <STRONG>Custom Fields</STRONG> app (Business Context: <I>Procurement: Purchasing Document</I>) and created a new Text(1) or Indicator field called <CODE>YY1_PO_WF_APPROVED_PDH</CODE>. I made sure to enable its usage for the respective Form Templates.</P><P>Next, I implemented the BAdI&nbsp;<CODE>MMPUR_PO_OUTPUT_HEADER_EXT</CODE> to determine the workflow status. Here is the BAdI logic:</P><pre class="lia-code-sample language-abap"><code>SELECT SINGLE FROM i_purchaseorderapi01 WITH PRIVILEGED ACCESS FIELDS WHERE purchaseorder = @purchaseorder AND releaseisnotcompleted = <a href="https://community.sap.com/t5/user/viewprofilepage/user-id/1410599">@ABAP</a>_false AND purchasingprocessingstatus = '05' INTO (po_approved). IF sy-subrc = 0. purdoc_extension-yy1_po_wf_approved_pdh = 'X'. ENDIF.</code></pre><P>&nbsp;After downloading the Content Form XML/XDP again, the newly added custom field was sitting right there in the Data View palette.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="kamilmirza_0-1774947710287.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/391475i9EAE54BF36317ADC/image-size/medium?v=v2&amp;px=400" role="button" title="kamilmirza_0-1774947710287.png" alt="kamilmirza_0-1774947710287.png" /></span></P><H3 id="toc-hId-1529275972">Step 3: Form Layout Setup</H3><P>Now, let’s jump into Adobe LiveCycle Designer to actually build the layout.</P><P>I added the DRAFT image inside a subform (named&nbsp;<CODE>formWatermark</CODE>) on both of the Master Pages: <CODE>mst1</CODE> (the first page) and <CODE>mst2</CODE> (subsequent pages).</P><BLOCKQUOTE><P><STRONG>Note:</STRONG> Make sure your <CODE>formWatermark</CODE> subform is set to <STRONG>Positioned</STRONG> (not Flowed) in the Object palette, and right-click to select <STRONG>Send to Back</STRONG>. This ensures it acts as a true background watermark and doesn't push your main content areas down.</P></BLOCKQUOTE><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="kamilmirza_1-1774947983597.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/391478i0B6EC987AC53EAA7/image-size/medium?v=v2&amp;px=400" role="button" title="kamilmirza_1-1774947983597.png" alt="kamilmirza_1-1774947983597.png" /></span></P><P>Here is where we hit the major roadblock: <STRONG>How do we access the master page watermark subform from the content form? Or conversely, how do we access the content form data from the master page?</STRONG></P><P>This can be achieved from either side using a simple <CODE>xfa.resolveNode</CODE> trick. You only need to use one of the following methods/approaches.</P><BLOCKQUOTE><P><STRONG>Note:</STRONG> For both approaches, ensure your Script Editor dropdowns are set to <STRONG>Language: JavaScript</STRONG> and <STRONG>Run At: Server</STRONG>. In S/4HANA Public Cloud, form rendering happens on the Server.&nbsp;</P></BLOCKQUOTE><H4 id="toc-hId-1461845186">Method #1: Controlling it from the Master Template Form</H4><P>To access our custom field value from the Content template form dataset <I>within</I> the Master template form, we need the absolute path of the field from the Content template's data view (e.g., <CODE>PurchaseOrderNode.YY1_PO_WF_APPROVED_PDH</CODE>).</P><P>We concatenate <CODE>xfa.datasets.data.Form.</CODE> with our custom field path. Place this JavaScript logic on the <CODE>formWatermark</CODE> subform's <CODE>initialize</CODE> event:</P><pre class="lia-code-sample language-javascript"><code>var WFStatusNode = xfa.resolveNode("xfa.datasets.data.Form.PurchaseOrderNode.YY1_PO_WF_APPROVED_PDH"); if (WFStatusNode.value === "X") { this.presence = "hidden"; } else { this.presence = "visible"; }</code></pre><H4 id="toc-hId-1265331681">Method #2: Controlling it from the Content Template Form</H4><P>Alternatively, we can access the master page watermark subforms directly from within the content template form by prefixing the path with <CODE>#pageSet[0].</CODE>.</P><P>Place this JavaScript code on the <CODE>YY1_PO_WF_APPROVED_PDH</CODE> field's <CODE>initialize</CODE> event:</P><pre class="lia-code-sample language-javascript"><code>var firstPageWatermarkNode = xfa.resolveNode("#pageSet[0].mst1.formWatermark"); var subsequentPageWatermarkNode = xfa.resolveNode("#pageSet[0].mst2.formWatermark"); if (this.rawValue === "X") { firstPageWatermarkNode.presence = "hidden"; subsequentPageWatermarkNode.presence = "hidden"; } else { firstPageWatermarkNode.presence = "visible"; subsequentPageWatermarkNode.presence = "visible"; }</code></pre><H3 id="toc-hId-939735457">The Final Result</H3><P>After choosing your preferred approach, upload the forms (Master and Content) back into the system and test your output.</P><P>When the PO is still in approval:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="kamilmirza_2-1774949879329.png" style="width: 200px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/391511iA07E5979F548E7B8/image-size/small?v=v2&amp;px=200" role="button" title="kamilmirza_2-1774949879329.png" alt="kamilmirza_2-1774949879329.png" /></span></P><P>And once the approval is fully completed:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="kamilmirza_3-1774949900763.png" style="width: 200px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/391512i390A5DB737D1E2B4/image-size/small?v=v2&amp;px=200" role="button" title="kamilmirza_3-1774949900763.png" alt="kamilmirza_3-1774949900763.png" /></span></P><P>The draft watermark completely vanishes!</P><P>It’s a relatively simple requirement that forces you to touch a few different areas of S/4HANA Cloud Extensibility, combining the <CODE>MMPUR_PO_OUTPUT_HEADER_EXT</CODE> BAdI with a little Adobe Forms JavaScript gets the job done perfectly.</P><P>Have you tackled similar form requirements in Public Cloud recently? Let me know your approach in the comments.</P> 2026-04-01T09:29:57.553000+02:00 https://community.sap.com/t5/artificial-intelligence-blogs-posts/how-i-connected-claude-ai-to-my-sap-abap-system-using-mcp-a-complete/ba-p/14365831 How I Connected Claude AI to My SAP ABAP System Using MCP — A Complete Windows Guide 2026-04-07T12:35:07.976000+02:00 Ahmed_Mosbah https://community.sap.com/t5/user/viewprofilepage/user-id/2292286 <P class=""><STRONG>Introduction</STRONG></P><P>The SAP developer community has been buzzing about connecting Claude AI&nbsp;directly to live SAP ABAP systems using MCP (Model Context Protocol) — reading code, modifying objects, creating transports, and activating changes, all from a natural language chat interface.</P><P>I tried it myself on Windows, and it works. This blog walks you through exactly how to set it up.</P><HR /><P class=""><STRONG>What is MCP?</STRONG></P><P class="">MCP (Model Context Protocol) is an open standard that lets AI models like Claude connect to external tools and data sources. Think of it as a plugin system for AI — instead of just answering questions from training data, Claude can actually <EM>call tools</EM> that interact with real systems.</P><P class="">For SAP developers, this means Claude can:</P><UL class=""><LI>Read your actual ABAP code directly from your system</LI><LI>Write and modify objects</LI><LI>Run syntax checks</LI><LI>Create transport requests</LI><LI>Activate objects</LI></UL><P class="">All without you copy-pasting anything.</P><HR /><P class=""><STRONG>The Architecture</STRONG></P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>Claude Desktop / Claude Code CLI</SPAN><SPAN> ↕ MCP Protocol</SPAN><SPAN> ┌──────────────────────────┐</SPAN><SPAN> │ mcp-abap-adt │ ← Read-only (13 tools)</SPAN><SPAN> │ mcp-abap-abap-adt-api │ ← Full CRUD (30 tools)</SPAN><SPAN> └──────────────────────────┘</SPAN><SPAN> ↕ ADT REST API</SPAN><SPAN> Your SAP ABAP System</SPAN></CODE></PRE></DIV></DIV><P class="">Both MCP servers were built by Mario Andreschak and communicate with SAP via the same ADT (ABAP Development Tools) API that Eclipse uses under the hood.</P><HR /><P class=""><STRONG>Prerequisites</STRONG></P><P class="">Before starting, you need:</P><UL class=""><LI>Windows 10 or 11 (64-bit)</LI><LI>An SAP ABAP system with <CODE>/sap/bc/adt</CODE> active in SICF</LI><LI>A user with <CODE>SAP_ADT_DEVELOPER</CODE> role (or equivalent)</LI><LI>A Claude Pro/Max/Team subscription at claude.ai</LI><LI>Internet connection</LI></UL><HR /><P class=""><STRONG>Step 1 — Install Node.js</STRONG></P><P class="">Node.js is the runtime required by Claude Code CLI and the MCP servers.</P><OL class=""><LI>Go to <STRONG><A class="" href="https://nodejs.org" target="_blank" rel="noopener nofollow noreferrer">https://nodejs.org</A></STRONG> and download the LTS version</LI><LI>Install with all defaults</LI><LI>Verify in Command Prompt:</LI></OL><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>node -v → v24.x.x</SPAN><SPAN>npm -v → 11.x.x</SPAN></CODE></PRE></DIV></DIV><HR /><P class=""><STRONG>Step 2 — Install Git for Windows</STRONG></P><P class="">Git provides the bash shell Claude Code requires on Windows.</P><OL class=""><LI>Go to <STRONG><A class="" href="https://git-scm.com/downloads/win" target="_blank" rel="noopener nofollow noreferrer">https://git-scm.com/downloads/win</A></STRONG> and download the installer</LI><LI>During setup, on the PATH screen select: <EM>"Git from the command line and also from 3rd-party software"</EM></LI><LI>Complete with all other defaults</LI></OL><HR /><P class=""><STRONG>Step 3 — Install Claude Code CLI</STRONG></P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>npm install -g @anthropic-ai/claude-code</SPAN><SPAN>claude --version</SPAN></CODE></PRE></DIV></DIV><P class="">Then log in:</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>claude</SPAN></CODE></PRE></DIV></DIV><P class="">Select option 1 (Claude subscription), log in via browser, return to terminal.</P><HR /><P class=""><STRONG>Step 4 — Install mcp-abap-adt (Read-Only MCP Server)</STRONG></P><P class="">This server gives Claude read access to your SAP system with 13 tools including GetProgram, GetClass, GetFunction, GetTable, SearchObject, and more.</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>mkdir C:\Tools</SPAN><SPAN>cd C:\Tools</SPAN><SPAN>git clone https://github.com/mario-andreschak/mcp-abap-adt</SPAN><SPAN>cd mcp-abap-adt</SPAN><SPAN>npm install</SPAN><SPAN>npm run build</SPAN></CODE></PRE></DIV></DIV><P class="">Create a <CODE>.env</CODE> file in the folder:</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>SAP_URL=https://your-sap-system.com:44300</SPAN><SPAN>SAP_USERNAME=YOUR_USERNAME</SPAN><SPAN>SAP_PASSWORD=YOUR_PASSWORD</SPAN><SPAN>SAP_CLIENT=300</SPAN><SPAN>TLS_REJECT_UNAUTHORIZED=0</SPAN></CODE></PRE></DIV></DIV><P class="">Register with Claude Code:</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>claude mcp add mcp-abap-adt node C:/Tools/mcp-abap-adt/dist/index.js</SPAN><SPAN>claude mcp list</SPAN></CODE></PRE></DIV></DIV><P class="">You should see: <CODE>mcp-abap-adt: ✓ Connected</CODE></P><HR /><P class=""><STRONG>Step 5 — Install mcp-abap-abap-adt-api (Full CRUD Server)</STRONG></P><P class="">This is the powerful one — 30 tools including read, write, syntax check, activate, lock/unlock, and transport management.</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>cd C:\Tools</SPAN><SPAN>git clone https://github.com/mario-andreschak/mcp-abap-abap-adt-api.git</SPAN><SPAN>cd mcp-abap-abap-adt-api</SPAN><SPAN>npm install</SPAN><SPAN>npm run build</SPAN></CODE></PRE></DIV></DIV><P class="">Create <CODE>.env</CODE> (note: slightly different variable names):</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>SAP_URL=https://your-sap-system.com:44300</SPAN><SPAN>SAP_USER=YOUR_USERNAME</SPAN><SPAN>SAP_PASSWORD=YOUR_PASSWORD</SPAN><SPAN>SAP_CLIENT=300</SPAN><SPAN>SAP_LANGUAGE=EN</SPAN><SPAN>NODE_TLS_REJECT_UNAUTHORIZED=0</SPAN></CODE></PRE></DIV></DIV><P class="">Register:</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>claude mcp add mcp-abap-adt-api node C:/Tools/mcp-abap-abap-adt-api/dist/index.js</SPAN></CODE></PRE></DIV></DIV><HR /><P class=""><STRONG>Step 6 — Setup Claude Desktop (GUI Interface)</STRONG></P><P class="">Claude Desktop is where it really comes alive — a beautiful chat UI like the LinkedIn video.</P><OL class=""><LI>Download from <STRONG><A class="" href="https://claude.ai/download" target="_blank" rel="noopener nofollow noreferrer">https://claude.ai/download</A></STRONG></LI><LI>Install and log in</LI><LI>Go to <STRONG>☰ → Settings → Developer → Edit Config</STRONG></LI><LI>Replace the content with:</LI></OL><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">json</DIV><DIV class=""><PRE><CODE><SPAN><SPAN class="">{</SPAN> </SPAN><SPAN> <SPAN class="">"mcpServers"</SPAN><SPAN class="">:</SPAN> <SPAN class="">{</SPAN> </SPAN><SPAN> <SPAN class="">"mcp-abap-adt"</SPAN><SPAN class="">:</SPAN> <SPAN class="">{</SPAN> </SPAN><SPAN> <SPAN class="">"command"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"C:\\Program Files\\nodejs\\node.exe"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"args"</SPAN><SPAN class="">:</SPAN> <SPAN class="">[</SPAN><SPAN class="">"C:\\Tools\\mcp-abap-adt\\dist\\index.js"</SPAN><SPAN class="">]</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"env"</SPAN><SPAN class="">:</SPAN> <SPAN class="">{</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_URL"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"https://your-sap-system.com:44300"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_USERNAME"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"YOUR_USERNAME"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_PASSWORD"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"YOUR_PASSWORD"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_CLIENT"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"300"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"TLS_REJECT_UNAUTHORIZED"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"0"</SPAN> </SPAN><SPAN> <SPAN class="">}</SPAN> </SPAN><SPAN> <SPAN class="">}</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"mcp-abap-adt-api"</SPAN><SPAN class="">:</SPAN> <SPAN class="">{</SPAN> </SPAN><SPAN> <SPAN class="">"command"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"C:\\Program Files\\nodejs\\node.exe"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"args"</SPAN><SPAN class="">:</SPAN> <SPAN class="">[</SPAN><SPAN class="">"C:\\Tools\\mcp-abap-abap-adt-api\\dist\\index.js"</SPAN><SPAN class="">]</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"env"</SPAN><SPAN class="">:</SPAN> <SPAN class="">{</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_URL"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"https://your-sap-system.com:44300"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_USER"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"YOUR_USERNAME"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_PASSWORD"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"YOUR_PASSWORD"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_CLIENT"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"300"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"SAP_LANGUAGE"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"EN"</SPAN><SPAN class="">,</SPAN> </SPAN><SPAN> <SPAN class="">"NODE_TLS_REJECT_UNAUTHORIZED"</SPAN><SPAN class="">:</SPAN> <SPAN class="">"0"</SPAN> </SPAN><SPAN> <SPAN class="">}</SPAN> </SPAN><SPAN> <SPAN class="">}</SPAN> </SPAN><SPAN> <SPAN class="">}</SPAN> </SPAN><SPAN><SPAN class="">}</SPAN></SPAN></CODE></PRE></DIV></DIV><BLOCKQUOTE><P class=""><span class="lia-unicode-emoji" title=":warning:">⚠️</span> <STRONG>Windows-specific tip:</STRONG> You MUST use the full path <CODE>C:\\Program Files\\nodejs\\node.exe</CODE> — using just <CODE>"node"</CODE> does not work in Claude Desktop on Windows. Also note double backslashes <CODE>\\</CODE> in all paths.</P></BLOCKQUOTE><OL class=""><LI>Kill Claude in Task Manager and reopen</LI><LI>Go back to Settings → Developer — you should see both servers listed as <STRONG>running</STRONG> <span class="lia-unicode-emoji" title=":white_heavy_check_mark:">✅</span></LI></OL><HR /><P class=""><STRONG>Step 7 — Add Free Official SAP MCP Servers</STRONG></P><P class="">Bonus: Claude Desktop has a built-in directory of official SAP MCP servers. Click <EM>"Connect your tools to Claude"</EM> at the bottom of the chat, search for "SAP", and add:</P><UL class=""><LI><STRONG>SAPUI5 MCP Server</STRONG> — for UI5 development</LI><LI><STRONG>SAP CAP MCP Server</STRONG> — for CAP projects</LI><LI><STRONG>SAP Fiori MCP Server</STRONG> — for Fiori Elements apps</LI></UL><P class="">Also add these free hosted servers to Claude Code CLI (no installation needed):</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class="">cmd</DIV><DIV class=""><PRE><CODE><SPAN>claude mcp add --transport http abap-docs https://mcp-abap.marianzeis.de/mcp</SPAN><SPAN>claude mcp add --transport http sap-docs https://mcp-sap-docs.marianzeis.de/mcp</SPAN></CODE></PRE></DIV></DIV><P class="">These give Claude access to the full ABAP keyword documentation across 8 SAP releases, ABAP cheat sheets, CAP docs, UI5 docs, and SAP Community posts.</P><HR /><P class=""><STRONG>Testing It</STRONG></P><P class="">Open Claude Desktop, create a New Chat, and type:</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>Get the source code of program SAPMV45A</SPAN></CODE></PRE></DIV></DIV><P class="">Watch Claude automatically call your SAP system, retrieve the source code, and explain it — all in seconds.</P><P class="">For write operations (test on $TMP objects only!):</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>Find a simple Z program in $TMP, add a comment at the top </SPAN><SPAN>saying "Modified by Claude", save and activate it</SPAN></CODE></PRE></DIV></DIV><P class="">For complex workflows like the LinkedIn video:</P><DIV class=""><DIV class=""><DIV class=""><DIV class=""><DIV class="">&nbsp;</DIV><DIV class=""><DIV class="">&nbsp;</DIV></DIV></DIV></DIV></DIV><DIV class=""><PRE><CODE><SPAN>Connect to my SAP system. Copy class ZCL_SOURCE from package </SPAN><SPAN>ZPKG_A into ZPKG_B, rename it to ZCL_TARGET, change the </SPAN><SPAN>carrier_id in the SELECT for /DMO/CONNECTION, create a </SPAN><SPAN>transport and activate.</SPAN></CODE></PRE></DIV></DIV><HR /><P class=""><STRONG>Security Notes</STRONG></P><UL class=""><LI>Never commit <CODE>.env</CODE> files to Git</LI><LI>Change your SAP password if shared in screenshots</LI><LI>Use dedicated service accounts with minimum required authorizations</LI><LI>Only test write operations in $TMP before moving to real packages</LI><LI>The <CODE>TLS_REJECT_UNAUTHORIZED=0</CODE> flag disables SSL validation — use only in dev environments</LI><LI>Check your company's AI policy before sending code to external APIs</LI></UL><HR /><P class=""><STRONG>My Experience</STRONG></P><P class="">What surprised me most is how Claude handles the entire workflow autonomously. It doesn't just write code — it searches for the object, reads the source, understands the structure, reads class includes, creates the transport, locks the object, writes the code, runs a syntax check, activates, and unlocks. All from one natural language request.</P><P class="">&nbsp;</P><P class=""><STRONG>Important Hint</STRONG></P><P class="">It can make ABAP-specific mistakes (like forgetting RAP locking fields, or using reserved DDIC words). Always review AI-generated code before activating in production. But as a development accelerator and code reviewer, it's genuinely powerful.</P><HR /><P class=""><STRONG>References</STRONG></P><UL class=""><LI>GitHub: <A class="" href="https://github.com/mario-andreschak/mcp-abap-adt" target="_blank" rel="noopener nofollow noreferrer">mcp-abap-adt</A> — Mario Andreschak</LI><LI>GitHub: <A class="" href="https://github.com/mario-andreschak/mcp-abap-abap-adt-api" target="_blank" rel="noopener nofollow noreferrer">mcp-abap-abap-adt-api</A> — Mario Andreschak</LI><LI>GitHub: <A class="" href="https://github.com/secondsky/sap-skills" target="_blank" rel="noopener nofollow noreferrer">sap-skills</A> — 35 Claude Code plugins for SAP</LI><LI>Blog: <A class="" href="https://community.sap.com/t5/technology-blog-posts-by-members/feed-sap-help-ui5-apis-amp-sap-community-content-into-your-ai-with-this/ba-p/14195007" target="_blank">SAP Docs MCP Server</A> — Marian Zeis</LI><LI>Blog: <A class="" href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/claude-code-via-mcp-poor-man-s-joule-or-a-practical-tool/ba-p/14344261" target="_blank">Claude Code via MCP</A> — SAP Community</LI><LI>Blog: <A class="" href="https://community.sap.com/t5/artificial-intelligence-blogs-posts/installing-and-extending-an-abap-mcp-server-by-vibe-coding-with-claude-code/ba-p/14343600" target="_blank">Installing and Extending an ABAP MCP Server</A> — SAP Community</LI></UL><HR /><P class=""><EM>I hope this helps other ABAP developers get started. If you run into issues or have questions, feel free to comment below. Happy coding!</EM></P> 2026-04-07T12:35:07.976000+02:00 https://community.sap.com/t5/enterprise-architecture-blog-posts/cap-rap-or-both-stop-hiding-behind-it-depends/ba-p/14363902 CAP, RAP, or Both: Stop Hiding Behind 'It Depends' 2026-04-09T02:05:37.595000+02:00 walteraguerom https://community.sap.com/t5/user/viewprofilepage/user-id/141635 <P>I've read every major article on this topic. They all end the same way:</P><P><EM>"Both models are complementary. Choose based on your context. Use each for the right scenario."</EM></P><P>That is a technically accurate, professionally safe, and completely useless answer.</P><P>This article gives you the framework I actually use with clients — including the uncomfortable parts most posts skip: the staffing bias that impact architecture decisions, what to do when your client has thousands of Z-objects, why migrating RAP to CAP is not a refactor, and why CAP is the only model that enforces the Clean Core promise architecturally.</P><P>One thing upfront:<SPAN>&nbsp;</SPAN><STRONG>this is not an anti-ABAP article.</STRONG><SPAN>&nbsp;</SPAN>ABAP knowledge — deep understanding of business processes, transactional models, and SAP data structures accumulated over years — is one of the most valuable assets in enterprise</P><H2 id="toc-hId-1793252750">What We're Actually Debating</H2><P><STRONG>RAP (ABAP RESTful Application Programming Model)</STRONG><SPAN>&nbsp;</SPAN>is SAP's extension model for the S/4HANA core and ABAP Cloud environments. It's ABAP-native, optimized for extending standard SAP Business Objects with transactional consistency. SAP's answer to "how do I extend S/4HANA without modifying standard code."</P><P><STRONG>CAP (Cloud Application Programming Model)</STRONG><SPAN>&nbsp;</SPAN>is SAP's framework for building cloud-native services on SAP BTP. Node.js and Java, BTP Cloud Foundry and Kyma, multitenancy, eventing, and OData/GraphQL out of the box. SAP's answer to "how do I build new business capabilities that live outside the S/4HANA core."</P><P>Same goal — Clean Core, BTP-native development. Fundamentally different execution contexts.</P><H2 id="toc-hId-1596739245">The Uncomfortable Truth First</H2><P>Most teams choosing between CAP and RAP are not making a pure architectural decision.</P><P>They're making a decision shaped by team composition.</P><P>An ABAP-heavy organization will present RAP as the natural choice for almost any BTP extension. The justification will sound architectural: "We need access to S/4HANA data," "We want to leverage existing ABAP logic," "RAP is Clean Core approved." All of those statements can be true and still be a rationalization. The real driver is often simpler: the team knows ABAP, so RAP wins.</P><P>This is a systemic pattern worth naming explicitly — because when staffing drives architecture, the decisions look reasonable one at a time and catastrophic in aggregate. The job of a principal architect is to separate these two questions before the decision is made.</P><H2 id="toc-hId-1400225740">When RAP Is Genuinely the Right Answer</H2><H3 id="toc-hId-1332794954">1. Extending Standard SAP Business Objects</H3><P>If you need to extend standard S/4HANA entities — Sales Orders, Purchase Requisitions, Business Partners, Material Documents — RAP is purpose-built for this. Proper lock handling, transactional consistency, draft management, clean integration with standard SAP workflows. Trying to replicate this via CAP calling S/4HANA APIs introduces latency, complexity, and consistency gaps that are difficult to manage at scale. For tight S/4HANA core extensions, RAP's native access is a genuine advantage, not just familiarity.</P><H3 id="toc-hId-1136281449">2. On-Premise + Cloud Parity Requirements</H3><P>RAP runs on both on-premise ABAP Platform and ABAP Cloud. CAP is cloud-only. Hybrid deployment, phased cloud migration, regulated industries with on-premise constraints — RAP is the only viable option when parity is required.</P><H3 id="toc-hId-939767944">3. Maximizing Existing ABAP Investment</H3><P>Complex, well-tested ABAP business logic that needs to be exposed as a service can be wrapped with a Clean Core API facade in RAP without rewriting it. Legitimate — with the caveat covered in the Z section below.</P><H3 id="toc-hId-743254439">4. Simple, Bounded In-App Extensions</H3><P>A single-source, single-consumer extension with no external integrations and no scalability concerns does not need the infrastructure overhead of CAP. Don't over-engineer.</P><H2 id="toc-hId-417658215">When CAP Is the Right Answer — Which Is More Often Than You Think</H2><H3 id="toc-hId-350227429">1. Multi-Source Data Scenarios</H3><P>The moment your extension needs data from more than one system, CAP is the correct choice. CAP's service layer was designed for data federation. RAP operating across multiple external sources becomes a manual integration exercise.</P><H3 id="toc-hId-153713924">2. Independent Scalability</H3><P>Side-by-side BTP extensions with variable load profiles should not be constrained by ABAP runtime characteristics. CAP on BTP Cloud Foundry or Kyma scales horizontally.</P><H3 id="toc-hId--118030950">3. Talent Pool and Long-Term Maintainability</H3><P>The global Node.js and Java developer pool is orders of magnitude larger than ABAP Cloud specialists. But the real point is different: the scarce resource in SAP programs is not syntax knowledge — it's SAP business process knowledge. An architecture that requires ABAP Cloud specialists to maintain it creates organizational dependency risk. An ABAP architect who already has the process knowledge and adds CAP to their toolkit is the most valuable person in the room.</P><H3 id="toc-hId--314544455">4. Multi-Tenant SaaS and Reusable Services</H3><P>CAP's multitenancy model is production-grade out of the box. RAP was not designed for this.</P><H3 id="toc-hId--511057960">5. Non-SAP Ecosystem Integration</H3><P>When your extension lives at the intersection of SAP and non-SAP systems, CAP's polyglot nature is a structural advantage. Building this in RAP means engineering brittle ABAP-to-external-API bridges.</P><H3 id="toc-hId--707571465">6. Survival of SAP Upgrade Cycles</H3><P>CAP extensions communicate with S/4HANA via stable, versioned APIs. They have no ABAP lifecycle. This connects directly to the Clean Core argument below.</P><H2 id="toc-hId--610681963">The Big Z Problem</H2><P>Most clients don't arrive at this debate with a clean slate. They arrive with 1,000, 2,000, sometimes 5,000 Z-objects accumulated over decades of ECC customization. The first proposal is almost always:<SPAN>&nbsp;</SPAN><EM>"Let's migrate the Zs to RAP."</EM></P><P>This is the wrong answer — and it is expensive.</P><P>The right question, before any migration decision, is:<SPAN>&nbsp;</SPAN><STRONG>why does each Z-object exist?</STRONG></P><P><STRONG>Category 1 — SAP now covers it natively (retire it)</STRONG><BR />A significant portion of Z-objects from ECC exist because SAP didn't have that functionality in 2005. S/4HANA and BTP may have it natively today. Before migrating anything, check whether SAP standard now covers the need. If it does: retire the Z. Don't migrate what you should delete.&nbsp;</P><P><STRONG>Category 2 — Genuine core business object extension (evaluate RAP)</STRONG><BR />Some Z-objects encode real business logic tightly coupled to SAP transactional objects — custom validations on Sales Orders, derivations on Financial documents, extensions to MM flows. These are legitimate RAP candidates because the coupling is intentional and the transactional integrity requirement is real.</P><P><STRONG>Category 3 — Side-by-side logic that never belonged in the core (evaluate CAP with bias)</STRONG><BR />Many Z-objects are reporting utilities, data extraction routines, integration helpers, or workflow logic placed inside the ABAP stack out of convenience, not architecture. These should be evaluated for CAP first — finally living where they should have lived from the beginning. One qualifier: if the logic requires HANA-native pushdown on large datasets (financial close, ATP, margin analysis at scale), or participates in SAP's transactional determination chain, evaluate before rebuilding. The default is still CAP. The exception needs justification.</P><P>The Big Z is not a RAP migration backlog. It's a forcing function to finally answer which of your customizations your business actually needs, which SAP now covers natively, and which were architectural accidents waiting to be corrected.</P><P>And for the Zs that survive the triage but can't be rewritten this quarter — wrap them. A clean API boundary around legacy logic is not technical debt; it's the first act of modernization. What you cannot afford is leaving Z-code directly exposed. That's how "temporary" becomes permanent.</P><H2 id="toc-hId--807195468">The CAP First Decision Protocol</H2><P><STRONG>CAP First</STRONG><SPAN>&nbsp;</SPAN>means the burden of proof shifts. The default is CAP. RAP must earn its place by satisfying a specific gate.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="diagram-cap-rap-decision (3).png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/392170iA2CA13F50E174F9B/image-size/large?v=v2&amp;px=999" role="button" title="diagram-cap-rap-decision (3).png" alt="diagram-cap-rap-decision (3).png" /></span></P><P><STRONG>The only gate that stops CAP:</STRONG><SPAN>&nbsp;</SPAN>transactional consistency with a standard SAP Business Object, bounded to S/4HANA data, with no external systems, no multi-tenancy, and no independent scalability requirements.</P><P>One honest prerequisite:<SPAN>&nbsp;</SPAN><STRONG>CAP First is the right posture for organizations that have already invested in BTP platform maturity</STRONG><SPAN>&nbsp;</SPAN>— an operational subaccount, CI/CD for Node.js or Java, and the operational capability for Cloud Foundry or Kyma workloads. For organizations that haven't built that foundation yet, CAP First is still the right destination — it comes with a deliberate enablement journey first. The posture doesn't change. The timeline does.</P><P>Why does the default posture matter? Because the cost of the wrong decision is asymmetric.</P><H2 id="toc-hId--1003708973">The Real Cost of Getting the Model Wrong</H2><P>A clarification worth making explicitly, because ABAP architects will correctly challenge a weaker version of this argument:</P><P><STRONG>Upgrading S/4HANA with existing RAP extensions is relatively low cost</STRONG><SPAN>&nbsp;</SPAN>— if your RAP uses only ABAP Cloud Released APIs (C1), which is what Clean Core RAP should do. SAP guarantees stability on released APIs across versions. ABAP teams who make this point are correct.</P><P>The cost argument I'm making is different. It's about<SPAN>&nbsp;</SPAN><STRONG>switching models</STRONG><SPAN>&nbsp;</SPAN>— what happens when you built in RAP and later discover that CAP was the right choice: multi-source data appeared, scalability became a requirement, the business needs this as a multi-tenant service.</P><P>RAP is ABAP. CAP is Node.js or Java. These are not different versions of the same language — different runtimes, different deployment models, different ecosystems entirely. When you migrate a RAP service to CAP:</P><UL><LI>The CDS data model needs to be rewritten in CAP CDS (similar syntax, different runtime behavior)</LI><LI>All business logic needs to be reimplemented in Node.js or Java — not ported, reimplemented</LI><LI>The deployment pipeline, CI/CD, monitoring, and operational model all change</LI><LI>The ABAP artifacts are retired, not converted</LI></UL><P>For a medium-complexity service: weeks to months. For a large one: a quarter or more. For a portfolio that grew because nobody pushed back: a program, not a project.</P><P><STRONG>The cost of the wrong default is asymmetric.</STRONG><SPAN>&nbsp;</SPAN>Not because RAP upgrades are expensive — they're not. But because choosing the wrong model and needing to switch is. CAP First reduces the risk of landing on that side.</P><P><EM>One variable that changes this equation: AI. Claude Code connected to SAP ADT via MCP can analyze RAP logic and generate CAP equivalents faster than before — it lowers the code generation cost. It does not replace the authorization model revalidation, the test suite rebuild, or the operational cutover, which is where most of the real effort lives. The fear factor drops. The effort doesn't disappear. That full conversation is a follow-up article.</EM></P><H2 id="toc-hId--1200222478">CAP Enforces the Clean Core Promise. RAP Requires Discipline to Maintain It.</H2><P>SAP's official definition of Clean Core: don't modify standard code, use the approved extensibility models. RAP is on that list — and a RAP extension using only ABAP Cloud Released APIs (C1) is genuinely Clean Core compliant by SAP's own definition. Let's be precise about this.</P><P>But Clean Core has a purpose beyond compliance:<SPAN>&nbsp;</SPAN><STRONG>the ability to upgrade your SAP core without touching your business logic.</STRONG><SPAN>&nbsp;</SPAN>Faster upgrades. Lower risk. Smaller impact windows.</P><P>Here is the real distinction between RAP and CAP on this point — and it is not about compliance. It is about enforcement.</P><P>Both models can satisfy the Clean Core compliance definition when implemented with discipline. The difference is what happens when discipline breaks down. In RAP, a team under delivery pressure can find paths to unreleased ABAP internals — friend class patterns, dynamic calls, legacy function module invocations. The architectural boundary exists as a rule, not a wall. In CAP, you are physically outside the ABAP stack. You cannot access unreleased internals because there is no path to them from a Node.js or Java runtime. The boundary is enforced by the architecture itself.</P><P><STRONG>RAP requires discipline to stay Clean Core. CAP makes it structurally difficult to leave.</STRONG></P><P>This is not a criticism of ABAP developers. It is a recognition that architectural guardrails matter most under pressure — and pressure is the normal operating condition of enterprise SAP programs.</P><P>A valid counterpoint here: ABAP Cloud on BTP — the ABAP Environment as a side-by-side deployment — does break the S/4HANA lifecycle dependency. The toolchain enforces Released APIs syntactically via the language version check, so the "discipline" argument partially weakens. But there is a distinction worth making: ABAP Cloud on BTP decouples you from S/4HANA's runtime lifecycle. CAP decouples you from the ABAP architecture itself. If your constraints are about upgrade survival, both work. If your constraints are about talent pool, integration patterns, and long-term architectural independence away from the ABAP stack — only one of them gets you there.</P><P>A CAP service communicates with S/4HANA through stable, versioned OData or API endpoints. It does not know what version of S/4HANA is running underneath. It has no ABAP lifecycle. It can be upgraded, redeployed, and scaled completely independently. RAP is the right direction. CAP is the destination. The difference is whether Clean Core survives contact with reality.</P><H2 id="toc-hId--1396735983">This Is Not Anti-ABAP. It's a Call to Deploy ABAP Knowledge Differently.</H2><P>Deep ABAP expertise — understanding transactional models, business process flows, SAP data structures built over decades — is irreplaceable. The scarce resource in SAP programs is not syntax knowledge. It is SAP business process knowledge. A Node.js developer learns the CAP framework in weeks. They do not learn how SAP processes an intercompany stock transfer in weeks. ABAP architects already have the hard part.</P><P>The problem is not ABAP knowledge. The problem is when that knowledge becomes a reason to avoid CAP rather than a foundation for it.</P><P>In 2026, with Claude Code connected to SAP ADT via MCP and Joule for Developers embedded in the SAP ecosystem, an experienced ABAP developer can build a production-grade CAP service with AI assistance in a fraction of the time it would have taken two years ago. The language gap has never been smaller to bridge. The "we don't have CAP developers" argument has never been weaker.</P><P>And the most mature SAP architectures don't choose one model. They use both deliberately:<SPAN>&nbsp;</SPAN><STRONG>RAP as the API layer of S/4HANA — the clean, stable interface that exposes core business objects. CAP as the orchestration and composition layer above it — multi-source, scalable, independently deployable.</STRONG><SPAN>&nbsp;</SPAN>That is not a compromise. That is the target state. ABAP architects who understand both are positioned to design it.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="diagram-cap-rap-decision-matrix (2).png" style="width: 744px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/392171i69B130241A8759B1/image-dimensions/744x618?v=v2" width="744" height="618" role="button" title="diagram-cap-rap-decision-matrix (2).png" alt="diagram-cap-rap-decision-matrix (2).png" /></span></P><H2 id="toc-hId--1593249488">A Challenge for Your Next Architecture Review</H2><P>Before your team decides on RAP — or commits to a Z-to-RAP migration program — answer four questions publicly in the room:</P><OL><LI><STRONG>For Z-objects:</STRONG><SPAN>&nbsp;</SPAN>Does each Z exist because SAP lacked functionality that it now has natively? If yes: retire it, don't migrate it.</LI><LI><STRONG>For new extensions:</STRONG><SPAN>&nbsp;</SPAN>Does this require transactional consistency with a standard SAP Business Object, bounded to S/4HANA data only? If yes: RAP is correct.</LI><LI><STRONG>For new extensions:</STRONG><SPAN>&nbsp;</SPAN>Does this require data from outside S/4HANA, independent scalability, or multi-tenant deployment? If yes: CAP is correct.</LI><LI><STRONG>Before committing to either:</STRONG><SPAN>&nbsp;</SPAN>Is RAP on the table because of architectural justification — or because of who is in the room?</LI></OL><P>Question 4 is the one that changes the outcome. And it takes organizational courage to ask it out loud.</P><P>The CAP vs. RAP debate is not a technology debate. It's an organizational clarity debate — and more often than not, an organizational courage debate. The teams that get this right are the ones willing to name what's actually driving the decision, separate ABAP expertise from ABAP default, and deploy both models where they genuinely belong.</P><H2 id="toc-hId--1621579302">References</H2><UL><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/rap-vs-cap-key-differences-between-the-two-programming-models/ba-p/13572799" target="_blank">RAP vs CAP - Key Differences between the Two Programming Models — SAP Community</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-members/cap-vs-rap-navigating-the-choice-of-sap-programming-models-for-your/ba-p/13579573" target="_blank">CAP vs. RAP: Navigating the Choice of SAP Programming Models — SAP Community</A></LI><LI><A href="https://help.sap.com/docs/abap-cloud/abap-rap/abap-restful-application-programming-model" target="_blank" rel="noopener noreferrer">ABAP RESTful Application Programming Model — SAP Help Portal</A></LI><LI><A href="https://pages.community.sap.com/topics/cloud-application-programming" target="_blank" rel="noopener noreferrer">SAP Cloud Application Programming Model — SAP Community</A></LI><LI><A href="https://qmacro.org/blog/posts/2024/11/07/five-reasons-to-use-cap/" target="_blank" rel="noopener nofollow noreferrer">Five Reasons to Use CAP — qmacro.org</A></LI><LI><A href="https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-sap/clean-core-extensibility-balancing-standardization-and-differentiation/ba-p/14260149" target="_blank">Clean Core Extensibility: Balancing Standardization and Differentiation — SAP Community</A></LI></UL><P><EM>Walter Aguero Machado —SAP Enterprise Architect | SAP BTP SME at Globant | SAP Certified Solution Architect &amp; BTP Administrator | ASUG Speaker</EM></P> 2026-04-09T02:05:37.595000+02:00 https://community.sap.com/t5/technology-blog-posts-by-members/custom-sorting-for-virtual-elements-in-rap/ba-p/14367132 Custom Sorting for Virtual Elements in RAP 2026-04-10T00:06:47.289000+02:00 sharathtm https://community.sap.com/t5/user/viewprofilepage/user-id/1874965 <H2 id="toc-hId-1793364319"><STRONG>Introduction</STRONG></H2><P>In the ABAP RESTful Application Programming Model (RAP), virtual elements are essential for displaying computed data that doesn't exist in the database—such as deriving a month or year from a timestamp. However, because these elements are calculated at runtime, they lack standard OData capabilities like server-side sorting and filtering. In this article, we will explore how to overcome these limitations by implementing a <STRONG>SADL exit</STRONG>. We’ll walk through how to enable full sorting and calculation capabilities for virtual elements, ensuring a seamless experience for the end user.</P><H2 id="toc-hId-1596850814">What are Virtual Elements in RAP?</H2><P>In the <STRONG>ABAP RESTful Application Programming Model (RAP)</STRONG>, a virtual element is a field defined in a CDS (Core Data Services) projection view that does not have a corresponding column in the underlying database table.</P><H2 id="toc-hId-1400337309">Real-Time Business Scenario: Sales Period Reporting</H2><P>In many SAP implementations, the business requires reports segmented by <STRONG>Month</STRONG> and <STRONG>Year</STRONG> (e.g., for Monthly Sales Performance). While the underlying database table stores a precise (Created On) date, it does not store the Month or Year as separate columns.</P><H3 id="toc-hId-1332906523">The Problem</H3><P>If we create a Fiori Elements app and want to show "Sales Month" and "Sales Year" as separate columns:</P><OL><LI><P><STRONG>Simple Virtual Elements</STRONG> can calculate these strings (e.g., "January", "2024").</P></LI><LI><P><STRONG>The Failure:</STRONG> When a user tries to sort the "Sales Month" column, the UI will throw an error or do nothing because the OData service doesn't know how to sort a field that doesn't exist in the database.</P></LI></OL><H3 id="toc-hId-1136393018">The Solution</H3><P>By using a <STRONG>SADL Exit</STRONG>, we "map" the virtual Month/Year fields back to the physical Sales date field. This allows the database to perform the sort on the actual date, while the user sees the sorted Month or Year on their screen.</P><H2 id="toc-hId-810796794">Implementation Steps</H2><H4 id="toc-hId-872448727">Step 1: Create a database table</H4><P>Define the physical storage. This is where the raw data lives before any calculations happen.</P><pre class="lia-code-sample language-abap"><code>@EndUserText.label : 'Sales table' @AbapCatalog.enhancement.category : #NOT_EXTENSIBLE @AbapCatalog.tableCategory : #TRANSPARENT @AbapCatalog.deliveryClass : #A @AbapCatalog.dataMaintenance : #RESTRICTED define table zsales_table { key client : abap.clnt not null; key sales_uuid : sysuuid_x16 not null; sales_id : abap.char(10); sales_date : abap.dats; @Semantics.amount.currencyCode : 'zsales_table.currency' total_amount : abap.curr(15,2); currency : abap.cuky; last_changed_at : timestampl; }</code></pre><H3 id="toc-hId-546852503">Step 2: Create a interface view on top of database table.</H3><P>This layer projects the database fields into a clean, business-oriented structure.</P><pre class="lia-code-sample language-abap"><code>@AbapCatalog.viewEnhancementCategory: [#NONE] @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Interface view for sales table' @Metadata.ignorePropagatedAnnotations: true @ObjectModel.usageType:{ serviceQuality: #X, sizeCategory: #S, dataClass: #MIXED } define root view entity zi_sales_table as select from zsales_table { key sales_uuid as SalesUuid, sales_id as SalesId, sales_date as SalesDate, @Semantics.amount. currencyCode: 'Currency' total_amount as TotalAmount, currency as Currency, last_changed_at as LastChangedAt }</code></pre><H3 id="toc-hId-350338998">&nbsp;Step 3: Create a Consumption view</H3><P>This is where the Virtual Elements are defined. We use annotations to link the UI to the specific ABAP logic for calculation and sorting.</P><pre class="lia-code-sample language-abap"><code>@AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Projection view for sales table' @Metadata.ignorePropagatedAnnotations: true define root view entity ZP_SALESPROJ provider contract transactional_query as projection on zi_sales_table { .facet: [{ type: #IDENTIFICATION_REFERENCE, position: 10, label: 'Salestable', targetQualifier: 'GENERAL', purpose: #STANDARD }] .lineItem: [{ position: 10, label: 'Sales Uuid' }] key SalesUuid, .lineItem: [{ position: 20, label: 'Sales Id' }] .identification: [{ position: 20, label: 'Sales Id' }] SalesId, .lineItem: [{ position: 30, label: 'Sales order date' }] .identification: [{ position: 30, label: 'Sales order date', qualifier: 'GENERAL' }] SalesDate, .lineItem: [{ position: 40, label: 'Sales order year' }] .identification: [{ position: 40, label: 'Sales order year', qualifier: 'GENERAL' }] @ObjectModel.virtualElement: true @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_SALES_VE_HANDLER' @ObjectModel.sort.transformedBy: 'ABAP:ZCL_SALES_VE_HANDLER' virtual SalesYear : abap.char(4), .lineItem: [{ position: 50, label: 'Sales order month' }] .identification: [{ position: 50, label: 'Sales order month' , qualifier: 'GENERAL' }] @ObjectModel.virtualElement: true @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_SALES_VE_HANDLER' @ObjectModel.sort.transformedBy: 'ABAP:ZCL_SALES_VE_HANDLER' virtual SalesMonth : abap.char(2), .lineItem: [{ position: 60, label: 'Total amount' }] .identification: [{ position: 60, label: 'Total amount' }] @Semantics.amount.currencyCode: 'Currency' TotalAmount, Currency }</code></pre><H4 id="toc-hId-282908212">Step 5:&nbsp;The Handler Class Logic</H4><P>This class implements two critical interfaces: <U><STRONG>if_sadl_exit_calc_element_read</STRONG></U>&nbsp;for the calculation and <U><STRONG>if_sadl_exit_sort_transform&nbsp;</STRONG></U>&nbsp;to enable sorting.</P><pre class="lia-code-sample language-abap"><code>CLASS zcl_sales_ve_handler DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES if_sadl_exit_calc_element_read. INTERFACES if_sadl_exit_sort_transform. PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zcl_sales_ve_handler IMPLEMENTATION. METHOD if_sadl_exit_calc_element_read~get_calculation_info. IF line_exists( it_requested_calc_elements[ table_line = 'SALESYEAR' ] ) OR line_exists( it_requested_calc_elements[ table_line = 'SALESMONTH' ] ). APPEND 'SALESDATE' TO et_requested_orig_elements. ENDIF. ENDMETHOD. METHOD if_sadl_exit_calc_element_read~calculate. DATA lt_data TYPE TABLE OF zp_salesproj WITH DEFAULT KEY. lt_data = CORRESPONDING #( it_original_data ). LOOP AT lt_data ASSIGNING FIELD-SYMBOL(&lt;fs_row&gt;). &lt;fs_row&gt;-SALESYEAR = &lt;fs_row&gt;-salesdate(4). &lt;fs_row&gt;-SALESMONTH = &lt;fs_row&gt;-salesdate+4(2). ENDLOOP. ct_calculated_data = CORRESPONDING #( lt_data ). ENDMETHOD. METHOD if_sadl_exit_sort_transform~map_element. CASE iv_element. WHEN 'SALESYEAR' OR 'SALESMONTH'. " Map the UI sort request to the database field 'SALESDATE' APPEND VALUE #( name = 'SALESDATE' ) TO et_sort_elements. ENDCASE. ENDMETHOD. ENDCLASS.</code></pre><H3 id="toc-hId--117919381">Result:</H3><P><BR />With the handler class implemented, the <STRONG>Sales order month and Sales order year</STRONG> ( Virtual Elements) now behaves like a standard database fields.<BR /><BR /></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="sharathtm_0-1775541139507.png" style="width: 0px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394078i308E9AD112A3DFDF/image-size/small?v=v2&amp;px=200" width="0" height="0" role="button" title="sharathtm_0-1775541139507.png" alt="sharathtm_0-1775541139507.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="sharathtm_1-1775541190320.png" style="width: 624px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/394080i8A95E257B9CF5997/image-dimensions/624x256?v=v2" width="624" height="256" role="button" title="sharathtm_1-1775541190320.png" alt="sharathtm_1-1775541190320.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="sharathtm_0-1775714874405.png" style="width: 599px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/395268i96C104E304776015/image-dimensions/599x226?v=v2" width="599" height="226" role="button" title="sharathtm_0-1775714874405.png" alt="sharathtm_0-1775714874405.png" /></span></P><P>&nbsp;</P> 2026-04-10T00:06:47.289000+02:00