https://raw.githubusercontent.com/ajmaradiaga/feeds/main/scmt/topics/ABAP-Cloud-blog-posts.xmlSAP Community - ABAP Cloud2025-02-12T06:00:00.716653+00:00python-feedgenABAP Cloud blog posts in SAP Communityhttps://community.sap.com/t5/technology-blogs-by-members/dependency-inversion-in-abap-practical-guide/ba-p/13934270Dependency Inversion in ABAP : Practical Guide2024-11-18T12:12:01.010000+01:00hazem2020https://community.sap.com/t5/user/viewprofilepage/user-id/861936<P><STRONG>Introduction: Applying Design Principles in ABAP </STRONG></P><P>In ABAP development, many of us don't always focus on design principles and patterns, especially since our work often revolves around customizing existing solutions or integrating systems rather than building software from scratch. However, understanding and applying these principles can still greatly improve the quality, maintainability, and scalability of our code.</P><P>In this blog, I want to share a practical example of how we can apply the <STRONG>Dependency Inversion</STRONG> principle, a key concept in the SOLID design patterns, in our everyday ABAP tasks.</P><P><STRONG>What is Dependency Inversion?</STRONG></P><P>Dependency Inversion suggests that the high-level modules (which contain the core logic of the application) should not rely directly on low-level modules (which handle specific tasks or data). Instead, both should depend on abstractions.</P><P><STRONG>Example Scenario: Checking the Budget</STRONG></P><P>Let’s imagine that we are working on a system where we need to check the budget for a Purchase Order (PO). Here’s how the process might unfold in a typical setup without considering Dependency Inversion:</P><OL><LI><STRONG>Step 1:</STRONG> Create a PO class that has a method <U><EM>Check_PO_Budget()</EM>.</U></LI><LI><STRONG>Step 2:</STRONG> Create a <EM><U>BudgetService </U></EM>class that interacts with the PO class.</LI><LI><STRONG>Step 3:</STRONG> In the <EM><U>BudgetService</U> </EM>class, you instantiate a PO object and call the <U><EM>po_obj->Check_PO_Budget()</EM></U> method.</LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="hazem2020_0-1731496983635.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/190450i22122D9C3646FACE/image-size/large?v=v2&px=999" role="button" title="hazem2020_0-1731496983635.png" alt="hazem2020_0-1731496983635.png" /></span></P><P><STRONG>The Problem with the Initial Approach</STRONG></P><P>In the example above, the <U><EM>BudgetService</EM> </U>class directly depends on the PO class to check the budget. the low and high levels are tightly coupled. The BudgetService class cannot function without initiating a PO object. Another thing f you need to add new functionality, such as checking the budget for a Sales Order (SO) instead of a PO, you have to modify the BudgetService class itself .</P><P><STRONG>Applying Dependency Inversion to Solve the Problem</STRONG></P><P>To solve these issues, we need to decouple the high-level module (<U><EM>BudgetService</EM></U>) from the low-level module (PO). both the high and low-level modules should depend on an interface ( Abstraction layer) that defines the behavior they require, rather than depending directly on each other.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="hazem2020_1-1731497123621.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/190454i1DA87A05BEF799FD/image-size/large?v=v2&px=999" role="button" title="hazem2020_1-1731497123621.png" alt="hazem2020_1-1731497123621.png" /></span></P><P><STRONG>Step-by-Step Approach:</STRONG></P><P><STRONG>Create an Interface</STRONG>: Define an interface that includes the method for checking the budget.</P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>INTERFACE zi_budge_services PUBLIC .
METHODS :
Check_budget RETURNING VALUE(r_out1) type string.
ENDINTERFACE.</code></pre><P> </P><P> </P><P><STRONG>Implement the Interface in the PO Class</STRONG></P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>CLASS zcl_po DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zi_budge_services.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_po IMPLEMENTATION.
METHOD zi_budge_services~check_budget.
r_out1 = 'Check budget for PO!' .
ENDMETHOD.
ENDCLASS.</code></pre><P> </P><P> </P><P><STRONG>Create the High-Level Class</STRONG>: The <U><EM>BudgetService</EM> </U>class will depend on the interface rather than the concrete PO class. </P><P>Note that : in the instructor we a type of the Interface so that we can inject any object or class that implements the interface and use its own functionality of checking the budget . this is a technique used to apply the Dependency Inversion called <STRONG>dependency injection ( Constructor Injection )</STRONG>.</P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>CLASS zcl_access_budget_service DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
methods constructor
IMPORTING !budget_service type REF TO zi_budge_services .
methods : run_budget_services RETURNING VALUE(r_output) type string .
PROTECTED SECTION.
PRIVATE SECTION.
data : budget_service type REF TO zi_budge_services .
ENDCLASS.
CLASS zcl_access_budget_service IMPLEMENTATION.
METHOD constructor.
me->budget_service = budget_service .
ENDMETHOD.
METHOD run_budget_services.
data(o1) = budget_service->check_budget( ) .
r_output = o1 .
ENDMETHOD.
ENDCLASS.</code></pre><P> </P><P> </P><P><STRONG>Test the logic:</STRONG></P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>CLASS ztest_di DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS ztest_di IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA(lo_po) = NEW zcl_po( ) .
data(lo_budget1) = new zcl_access_budget_service( lo_po ) .
data(output) = lo_budget1->run_budget_services( ) .
ENDMETHOD.
ENDCLASS.</code></pre><P> </P><P> </P><P><STRONG>Introducing New Functionalities Without Modifying High-Level Modules : </STRONG>The high level <U><EM>BudgetService </EM> </U>remains untouched. We will add a new budget checker (<U><EM>SO</EM></U>) then just Inject it into the BudgetService .</P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>CLASS zcl_so DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zi_budge_services.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_so IMPLEMENTATION.
METHOD zi_budge_services~check_budget.
r_out1 = 'Check budget for SO!' .
ENDMETHOD.
ENDCLASS.</code></pre><P> </P><P> </P><P>Nothing to be changed in the <U><EM>BudgetService </EM></U>main Class and only we Inject the <EM><U>SO</U> </EM>Object in the testing class like below </P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code> DATA(lo_so) = NEW zcl_so( ) .
data(lo_budget1) = new zcl_access_budget_service( lo_so ) .
data(output) = lo_budget1->run_budget_services( ) .</code></pre><P> </P><P> </P><P> </P><P><STRONG>Conclusion</STRONG></P><P>In the blog I tried to highlight the benefits of Dependency Inversion with Dependency Injection as below :</P><P> </P><UL><LI><STRONG>Decoupling</STRONG>: The high-level <EM><U>BudgetService</U> </EM>class is now independent of the low-level <U><EM>PO</EM> </U>and <EM><U>SO</U> </EM>classes. This makes it easier to change or replace them without affecting the core logic.</LI><LI><STRONG>Flexibility</STRONG>: New types of budget checkers (like <EM><U>PO_V2</U></EM> or <EM><U>SO</U></EM>) can be introduced with minimal impact on the existing system.</LI><LI><STRONG>Easier Maintenance</STRONG>: Changes in the low-level classes (e.g., the PO class) do not require changes in the high-level module (e.g., the <U><EM>BudgetService</EM> </U>class), reducing the risk of introducing bugs.</LI></UL><P>This is my first time to work with this pattern and I wanted to share what I have learned , So feel free to try it out in your projects and let me know your thoughts.</P><P> </P><P> </P><P> </P>2024-11-18T12:12:01.010000+01:00https://community.sap.com/t5/technology-blogs-by-sap/sap-btp-abap-environment-release-2411/ba-p/13940790SAP BTP ABAP Environment - Release 24112024-11-19T09:50:32.702000+01:00Nora_Klemphttps://community.sap.com/t5/user/viewprofilepage/user-id/1641196<H1 id="toc-hId-946503196">SAP BTP ABAP Environment - Release 2411</H1><P>As follow-up to our previous release <A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-btp-abap-environment-release-2408/ba-p/13801154" target="_blank">2408</A>, this blog post provides an update concerning our most recent release <STRONG>2411</STRONG>, which is available for customers and partners since November 16th. <SPAN>This particular release features highlights such as <STRONG>ABAP Cloud in SAP Build</STRONG>, a new approach to build <STRONG>Application Jobs</STRONG>, and the region-less subscription of the <STRONG>Landscape Portal</STRONG></SPAN><SPAN>.</SPAN></P><P>The complete list of all new features can be found on the <A href="https://help.sap.com/whats-new/7a822d3bcaa74f31b98fa315601e9c96?Software_Lifecycle=General+Availability&Version=ABAP+Environment+2411&locale=en-US" target="_blank" rel="noopener noreferrer">What´s New for SAP BTP ABAP Environment</A> page.</P><H4 id="toc-hId-1137237848">ABAP Development Tools (ADT)</H4><UL><LI>Creating an <STRONG>ABAP Cloud Project</STRONG> in the Context of the SAP BTP ABAP environment, a service key is no longer needed when creating an ABAP Cloud Project. You now enter the ABAP Service instance URL (<A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/creating-abap-cloud-project?version=sap_btp" target="_blank" rel="noopener noreferrer">details</A>)</LI><LI>Triggering <STRONG>Where-Used List for Usages of CDS Annotation</STRONG> to enable the investigation in which ABAP CDS an annotation is used</LI><LI>Displaying <STRONG>Field Characteristics for RAP Types</STRONG> in the Element Information Popup, The Element Information popup (F2) for RAP types shows additional field characteristics information such as mandatory:create, mandatory:execute or readonly (<A href="https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_field_char.htm" target="_blank" rel="noopener noreferrer">details</A>)</LI><LI><STRONG>Multi-Dimensional Analysis App Generator</STRONG>, you can now use the multi-dimensional analysis app generator wizard to create all ABAP development objects that are needed to build, expose, and deploy a multi-dimensional analysis Fiori app (<A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/generating-multi-dimensional-analysis-applications" target="_blank" rel="noopener noreferrer">details</A>)</LI><LI>Support of <STRONG>SAP Fiori launchpad app descriptor items</STRONG> in ABAP Development Tools for Eclipse, these items describe how an application is started and consist of a target mapping and one or more tiles, for more information see <A href="https://help.sap.com/docs/PRODUCTS/36609a00dcea4e6fa7c4ca2f2868e972/1d9deef79d7d4936850b2d6343206ec8.html?locale=en-US&version=Cloud" target="_blank" rel="noopener noreferrer">SAP Fiori Applications in the ABAP Environment</A> and <A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/working-with-launchpad-app-descriptor-items" target="_blank" rel="noopener noreferrer">Working with Launchpad App Descriptor Items</A></LI><LI><STRONG>Rerunning Unit Tests with Coverage</STRONG> in the ABAP Coverage view (<A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/evaluating-abap-unit-code-coverage-results" target="_blank" rel="noopener noreferrer">details</A>)</LI><LI><STRONG>Clearing Coverage results</STRONG>, you can now clear your coverage results in the ABAP Coverage view (<A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/evaluating-abap-unit-code-coverage-results" target="_blank" rel="noopener noreferrer">details</A>)</LI><LI><STRONG>ABAP Test Cockpit: ATC Check "Usage of Released APIs"</STRONG> <SPAN>can be run on Key User and ABAP Cloud objects</SPAN></LI></UL><H4 id="toc-hId-940724343">Reuse Services</H4><UL><LI>New Class Interface for <STRONG>Application Job Catalog Entries and Templates</STRONG>, with the new attribute-based class interface it is now possible to change the parameters, sections, and groups of a catalog entry (<A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/working-with-application-job-objects" target="_blank" rel="noopener noreferrer">details</A>)</LI><LI><STRONG>Business Rule Framework (BRF plus)</STRONG> is enhanced with a code generation service and an API introduced to facilitate the consumption of business rules within ABAP Cloud (<A href="https://help.sap.com/docs/PRODUCTS/36609a00dcea4e6fa7c4ca2f2868e972/69da3f86a5e24bd986d3125db1fe9238.html?locale=en-US&version=Cloud" target="_blank" rel="noopener noreferrer">details</A>)</LI><LI><STRONG>XCO XSLX</STRONG>: You can now style the cells of an Excel worksheet. You can also modify existing documents (<A href="https://help.sap.com/docs/PRODUCTS/36609a00dcea4e6fa7c4ca2f2868e972/c154dffe892b4d9ea4566722f0bcd5f1.html?locale=en-US&version=Cloud" target="_blank" rel="noopener noreferrer">details</A>)</LI><LI><STRONG>XCO CDS</STRONG>: You can now generate CDS external entities and logical external schemas, and you can now add comments and arithmetic expressions to CDS views (<A href="https://help.sap.com/docs/PRODUCTS/36609a00dcea4e6fa7c4ca2f2868e972/c154dffe892b4d9ea4566722f0bcd5f1.html?locale=en-US&version=Cloud" target="_blank" rel="noopener noreferrer">details</A>)</LI></UL><H4 id="toc-hId-744210838"><STRONG>UI Services and SAP Fiori Launchpad</STRONG></H4><UL><LI>Creating <STRONG>Launchpad App Descriptor Items</STRONG> (<A href="https://help.sap.com/docs/abap-cloud/abap-development-tools-user-guide/working-with-launchpad-app-descriptor-items" target="_blank" rel="noopener noreferrer">details</A>)</LI></UL><H4 id="toc-hId-547697333">Integration</H4><UL><LI>With Business Event Logging, you can <STRONG>capture and log business events locally</STRONG> within the ABAP environment</LI><LI>App <STRONG>Display Business Event Logs</STRONG>. It provides an overview of logged business events for different objects and event types. You can explore the details of the event with this app</LI><LI>App <STRONG>Display Business Events by Objects</STRONG>: It groups business events by instances of objects and object components</LI><LI>App <STRONG>Display Changes to Objects</STRONG>: You can see the changes for your objects on a field level as recorded in business event logging</LI></UL><H4 id="toc-hId-351183828">Security</H4><UL><LI>ABAP environment tenants are now equipped with a <STRONG>signed default client certificate</STRONG>, which is <STRONG>automatically rotated</STRONG> and can be used for customer managed integration scenarios</LI><LI>The communication scenario SAP_COM_0915 provides access to <STRONG>APIs to read the Read Access Logs</STRONG> from the system, the API can for instance be leveraged by a Security Incident and Event Management (SIEM) system</LI><LI>TLS 1.3, we now support <STRONG>Transport Layer Security 1.3</STRONG> for outbound HTTP, WebSocket RFC, and SMTP protocols</LI><LI>The system exposes <STRONG>APIs to retrieve customer-managed security settings</STRONG> in a read-only manner</LI></UL><H4 id="toc-hId-154670323">Custom Code Migration App</H4><UL><LI>Include <STRONG>ADT links</STRONG> in SAP S/4HANA Readiness Check Export, the export of ATC results for the SAP S/4HANA Readiness Check now includes HTTP(S) links, which enables you to navigate to the source code of example code in ADT for Eclipse. This new functionality is available in the Custom Code Migration app only (<A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/enable-usage-of-custom-code-migration-app?" target="_blank" rel="noopener noreferrer">details</A>)</LI><LI>New option to <STRONG>start analysis after project creation</STRONG>, you can now choose whether you would like to start the custom code analysis run automatically at project creation or whether you would like to schedule it manually after project creation (<A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/creating-custom-code-analysis-project" target="_blank" rel="noopener noreferrer">details</A>)</LI><LI>Changes in <STRONG>Scope Calculation Automation</STRONG>, you now need to initiate scope calculation manually after project creation, the scope calculation no longer starts automatically at project creation (<A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/dependency-analysis" target="_blank" rel="noopener noreferrer">details</A>)</LI></UL><H4 id="toc-hId--41843182">Cloud ATC</H4><UL><LI><STRONG>Change Validity Date for ATC Exemptions</STRONG> in the Approve ATC Exemptions App (<A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/approve-atc-exemptions" target="_blank" rel="noopener noreferrer">details</A>)</LI><LI><STRONG>Replication of ATC Exemptions from on-premise towards SAP BTP</STRONG>, Customers need to use transaction SATC_EXPORT_XMPT to download the exemptions from an on-premise ATC system (<A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/enable-usage-of-approve-atc-exemptions-app" target="_blank" rel="noopener noreferrer">details</A>)</LI></UL><H4 id="toc-hId--238356687">Technical Monitoring</H4><UL><LI>Enhanced app <STRONG>HANA Table Analysis</STRONG>: With the <STRONG>new Column Loads and Column Unloads screens in the HANA Table Analysis app</STRONG>, you can check how many columns of the tables in your HANA database have been loaded to or unloaded from the main storage (<A href="https://help.sap.com/docs/PRODUCTS/36609a00dcea4e6fa7c4ca2f2868e972/8ec349bd5fad4552a68f15d1c6909b60.html?locale=en-US&version=Cloud" target="_blank" rel="noopener noreferrer">details</A>)</LI><LI>New app <STRONG>HANA Memory Analysis</STRONG>: With the new app, you can get an overview of the memory consumption of the HANA memory components over time. This helps you to <STRONG>identify bottlenecks</STRONG> in your HANA memory (<A href="https://help.sap.com/docs/PRODUCTS/36609a00dcea4e6fa7c4ca2f2868e972/2ecdbdb73df542908a397c14dcb66382.html?locale=en-US&version=Cloud" target="_blank" rel="noopener noreferrer">details</A>)</LI></UL><H4 id="toc-hId--434870192">Lifecycle Management</H4><UL><LI>When cloning a software component, you can now optionally use the newly added parameters to request <STRONG>cloning a Bring Your Own Git (BYOG) repository</STRONG> (<A href="https://help.sap.com/docs/PRODUCTS/36609a00dcea4e6fa7c4ca2f2868e972/994c961dd666413e801df6c62cb727fc.html?locale=en-US&version=Cloud" target="_blank" rel="noopener noreferrer">details</A>)</LI></UL><H4 id="toc-hId--1129100792">abapGit</H4><UL><LI>Support of <STRONG>object deletions</STRONG>, it can now be exported from and imported to the ABAP environment with abapGit (<A href="https://help.sap.com/docs/PRODUCTS/36609a00dcea4e6fa7c4ca2f2868e972/b281f57d97414149b118f724a81d4ef2.html?locale=en-US&version=Cloud" target="_blank" rel="noopener noreferrer">details</A>)</LI></UL><H4 id="toc-hId--1325614297">Landscape Portal</H4><UL><LI>Extended Access, you can now <STRONG>access and subscribe to the Landscape Portal for SAP BTP ABAP Environment from every region</STRONG> that is available for the ABAP environment. In regions without SAP Continuous Integration and Delivery service, some applications in the Landscape Portal are limited or not available (<A href="https://help.sap.com/docs/help/d91c4152c3d74c12bc9bd4ed92681902/d9e865ad47204b80816b6f62af57b823.html" target="_blank" rel="noopener noreferrer">details</A>)</LI><LI>Deinstalling Products, the new <STRONG>Undeploy Product app</STRONG> in the<STRONG> </STRONG>Landscape Portal<STRONG> </STRONG>enables you to permanently deinstall existing products (<A href="https://help.sap.com/docs/help/d91c4152c3d74c12bc9bd4ed92681902/876ca74ce3e74f92bc0fbf1e784edf97.html" target="_blank" rel="noopener noreferrer">details</A>)</LI></UL>2024-11-19T09:50:32.702000+01:00https://community.sap.com/t5/technology-blogs-by-members/abap-object-oriented-programming-oop-builder-pattern-cloud-ready-version/ba-p/13946246ABAP Object Oriented Programming (OOP): Builder pattern Cloud Ready Version.2024-11-25T08:07:28.766000+01:00PrusakouIlyahttps://community.sap.com/t5/user/viewprofilepage/user-id/1769851<H1 id="toc-hId-946676988">Builder Pattern Cloud Ready Implementation</H1><P><SPAN>All code can be found in my GitHub repository: <A href="https://github.com/IlyaPrusakou/ABAPBuilderPattern" target="_blank" rel="noopener nofollow noreferrer">https://github.com/IlyaPrusakou/ABAPBuilderPattern </A></SPAN></P><P><SPAN>In this repository you can find implementation of Builder Pattern in ABAP. The main point is the realization of pattern made on special version of ABAP language - <STRONG>ABAP for Cloud Development</STRONG>. So that there is 100% cloud compatibility. </SPAN></P><P><SPAN>Just copy and use it.</SPAN></P><H2 id="toc-hId-879246202"><U>1. Introduction.</U></H2><P><SPAN>The Builder pattern is one of the classic creational design pattern. The main idea of the one is to separate process of creation of Product class (Product, Car, Car Schema and etc.) A logic for creation of Product class is handled into Builder class. </SPAN></P><P><SPAN>Below you can find<STRONG> Pattern Schemas</STRONG> and<STRONG> Implementation Details</STRONG>, you can skip theoretical notes and go to these sections.</SPAN></P><H2 id="toc-hId-682732697"><U>2. Theoretical notes.</U></H2><H3 id="toc-hId-615301911">2.1. Types of the Builder pattern</H3><P>There are 3 types of builder pattern I've differentiated. Each of them can be found correspondingly in GitHub files: <A href="https://github.com/IlyaPrusakou/ABAPBuilderPattern/tree/main/src/zpru_bld1" target="_blank" rel="noopener nofollow noreferrer">src/zpru_bld1</A>, <A href="https://github.com/IlyaPrusakou/ABAPBuilderPattern/tree/main/src/zpru_bld2" target="_blank" rel="noopener nofollow noreferrer">src/zpru_bld2</A>, <A href="https://github.com/IlyaPrusakou/ABAPBuilderPattern/tree/main/src/zpru_bld3" target="_blank" rel="noopener nofollow noreferrer">src/zpru_bld3</A>.</P><H4 id="toc-hId-547871125">2.1.1. Simple Builder:</H4><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PrusakouIlya_0-1732374558540.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/194748i4BDF076A6ABC2D73/image-size/medium?v=v2&px=400" role="button" title="PrusakouIlya_0-1732374558540.png" alt="PrusakouIlya_0-1732374558540.png" /></span></P><H4 id="toc-hId-351357620">2.1.2. Builder with Director</H4><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PrusakouIlya_1-1732374629840.png" style="width: 587px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/194749i0A6DBFF655567485/image-dimensions/587x113?v=v2" width="587" height="113" role="button" title="PrusakouIlya_1-1732374629840.png" alt="PrusakouIlya_1-1732374629840.png" /></span></P><H4 id="toc-hId-154844115">2.1.3. Builder with Director and Interfaces</H4><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PrusakouIlya_2-1732374697179.png" style="width: 606px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/194750iD0BC6D36CDB931AC/image-dimensions/606x274?v=v2" width="606" height="274" role="button" title="PrusakouIlya_2-1732374697179.png" alt="PrusakouIlya_2-1732374697179.png" /></span></P><H3 id="toc-hId--170752109">2.2. Semantical structure of pattern</H3><P>All classes and interfaces can play roles of:</P><OL><LI>Director</LI><LI>Builder</LI><LI>Product.</LI></OL><P>Regarding of Product role I would like to underline distinction of at least two type of specialization:</P><H4 id="toc-hId--238182895">2.2.1. Factual specialization</H4><P><SPAN>Factual specialization means that all instances of product has the same class or interface, but they differ by data preserved into. The example:</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PrusakouIlya_0-1732374945495.png" style="width: 548px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/194751i0F7AC3AE86785DE8/image-dimensions/548x195?v=v2" width="548" height="195" role="button" title="PrusakouIlya_0-1732374945495.png" alt="PrusakouIlya_0-1732374945495.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PrusakouIlya_1-1732374988207.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/194752i8FE53630221CC893/image-size/medium?v=v2&px=400" role="button" title="PrusakouIlya_1-1732374988207.png" alt="PrusakouIlya_1-1732374988207.png" /></span></P><P><SPAN>As you can see there are two instances of class Car, but they are varied with qualified field model, which can be read-only field, set inside constructor.</SPAN></P><H4 id="toc-hId--434696400">2.2.2. Type specialization</H4><P><SPAN>As you can guessed that type of specialization is based on usage of not only the same class with different values of qualified fields, but also different classes or interfaces. Moreover, there is room for amplification of interfaces raised. The same example:</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PrusakouIlya_2-1732375099394.png" style="width: 542px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/194753i0946A048D7F51FF7/image-dimensions/542x202?v=v2" width="542" height="202" role="button" title="PrusakouIlya_2-1732375099394.png" alt="PrusakouIlya_2-1732375099394.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PrusakouIlya_3-1732375160576.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/194754i4563D795515237BD/image-size/medium?v=v2&px=400" role="button" title="PrusakouIlya_3-1732375160576.png" alt="PrusakouIlya_3-1732375160576.png" /></span></P><P>Regarding Builder role I would elucidate method Build. The method creates an instance of Product and set all data, preserved in Builder instance, into product instance. We can set up builder once with setters methods. All the data will be plugged in Product instance. Each invocation of Build creates new instance of Product with data from Builder. The Builder is a source of data, along with that Product is a recipient of data. Moreover, there is space for implementation of specialization of product. For instance, Builder can have multiple Build methods (buildProductA, buildProductB and etc.), returning different instance setup or different class types.</P><P>Director role is just additional stage of Product creation. When Builder is a distinct layer for creation of Products, but Director is a layer to create or setup of Builders. Hence the question of specialization rises again there. For example, we can make multiple methods (setupBuilderA, setupBuilderB and etc.) for setup of different Builders.</P><H2 id="toc-hId--542120986"><U>3. Pattern Schemas.</U></H2><H3 id="toc-hId--1032037498">3.1. Simple Builder</H3><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Builder 1 UML schema.png" style="width: 624px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/194755i11DBE44C201AE777/image-dimensions/624x491?v=v2" width="624" height="491" role="button" title="Builder 1 UML schema.png" alt="Builder 1 UML schema.png" /></span></P><H3 id="toc-hId--1228551003">3.2. Builder with Director.</H3><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Builder 2 UML schema.png" style="width: 663px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/194756i4D4D1AF89ABD54F1/image-dimensions/663x738?v=v2" width="663" height="738" role="button" title="Builder 2 UML schema.png" alt="Builder 2 UML schema.png" /></span></P><H3 id="toc-hId--1425064508">3.3. Builder With Director and Interfaces</H3><P> <span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Builder 3 UML schema.png" style="width: 745px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/194761i6A736EBD897BE6F5/image-size/large?v=v2&px=999" role="button" title="Builder 3 UML schema.png" alt="Builder 3 UML schema.png" /></span></P><H2 id="toc-hId--1328175006"><U>4. Implementation Details</U></H2><H3 id="toc-hId--1818091518">4.1. Simple Builders</H3><OL><LI>Car class has private constructor an establish friendship with Car Builder class.</LI><LI>Car class has only getters methods to receive data from.</LI><LI>Car class has constructor taking all data to setup it as class attributes.</LI><LI>Builder contains only setter methods to setup builder data as class attributes.</LI><LI>Builder has build method, returning instance of Car class.</LI><LI>Builder's build method passes all data from Builder instance into constructor of Car class.</LI></OL><H3 id="toc-hId--2014605023">4.2. Simple Builders Usage pattern.</H3><P> </P><pre class="lia-code-sample language-abap"><code> " Create mercedes builder
" pass mandatory fields
DATA(lo_mercedes_builder) = NEW zpru_cl_bld1_car_builder( iv_id = '1'
iv_brand = 'MERCEDES'
iv_model = 'C 180 T-Model' ).
" pass optional fields into builder
lo_mercedes_builder->set_price('100000' )->set_multimedia( 'AVANTGARDE' )->set_equipment( 'Memory Package' )->set_assistance_system('Driving Assistance Package Plus' ).
" construct final object of mercedes
DATA(lo_mercedes_c_180) = lo_mercedes_builder->build( ).</code></pre><P> </P><H3 id="toc-hId-2083848768">4.3. Builder with Director</H3><OL><LI>1 - 6 points for Simple Builder are true</LI><LI>Director class has specialized methods to setup different Builders, e.g. buildMercedes, buildPorcshe and etc.</LI><LI>Director's specialized methods has importing parameter of type of Builder class(Builder Interface) to inject Builder instance</LI><LI>Director's methods provide distinguished setup for different Builders' instances.</LI></OL><H3 id="toc-hId-1887335263">4.4. Builder with Director Usage pattern</H3><P> </P><pre class="lia-code-sample language-abap"><code> DATA(lo_director) = NEW zpru_cl_bld2_car_director( ).
DATA(lo_mercedes_builder) = NEW zpru_cl_bld2_car_builder( iv_brand = 'MERCEDES'
iv_model = 'C 180 T-Model' ).
lo_director->build_mercedes( io_builder = lo_mercedes_builder ).
lo_mercedes_builder->set_color( 'BLUE' ).
lo_mercedes_builder->set_id( '1' ).
DATA(lo_mercedes_c180_1_blue) = lo_mercedes_builder->build( ).</code></pre><P> </P><DIV class=""><H3 id="toc-hId-1690821758">4.5. Builder With Director and Interfaces</H3></DIV><OL><LI>Basically, 1 - 6 points for Simple Builder are true.</LI><LI>Create common interface for all Product class(Car class and Car Schema class).</LI><LI>Create product specialized interfaces for Car entity and Car Schema entity.</LI><LI>Create common interface for Builder classes(Car Builder class and Car Schema class).</LI><LI>Create Builder specialized interfaces for Car Builder entity and Car Schema Builder entity.</LI><LI>Rework friendship inside Car and Car Schema classes, make it points onto Builder common interface.</LI><LI>Use type of product specialized interface as returning type of Builder's build methods.</LI><LI>Use type of builder specialized interface as importing type of Director's build methods.</LI></OL><H3 id="toc-hId-1662491944">4.6. Builder With Director and Interfaces Usage pattern.</H3><P> </P><pre class="lia-code-sample language-abap"><code> DATA lo_mercedes_builder_car TYPE REF TO zpru_if_bld3_builder_car.
DATA lo_mercedes_builder_schema TYPE REF TO zpru_if_bld3_builder_schema.
DATA lo_director TYPE REF TO zpru_cl_bld3_car_director.
lo_director = NEW zpru_cl_bld3_car_director( ).
lo_mercedes_builder_car = NEW zpru_cl_bld3_car_builder( iv_brand = 'MERCEDES'
iv_model = 'C 180 T-Model' ).
lo_director->build_mercedes_car( io_builder = lo_mercedes_builder_car ).
lo_mercedes_builder_car->zpru_if_bld3_builder~set_id( '1' ).
DATA(lo_mercedes_c180_car) = lo_mercedes_builder_car->build( ).
lo_mercedes_builder_schema = NEW zpru_cl_bld3_schema_builder( iv_brand = 'MERCEDES'
iv_model = 'C 180 T-Model' ).
lo_director->build_mercedes_schema( io_builder = lo_mercedes_builder_schema ).
lo_mercedes_builder_schema->zpru_if_bld3_builder~set_id( '2' ).
DATA(lo_mercedes_c180_schema) = lo_mercedes_builder_schema->build( ).</code></pre><P> </P><P> </P>2024-11-25T08:07:28.766000+01:00https://community.sap.com/t5/technology-blogs-by-sap/abap-ai-is-our-shared-treasure-abap-ai-is-on-its-way/ba-p/13947366“ABAP AI is our Shared Treasure” - ABAP AI is on its way.2024-11-25T08:44:38.882000+01:00lienardshttps://community.sap.com/t5/user/viewprofilepage/user-id/227111<P style=" text-align : justify; ">It’s time to talk about the announced ABAP AI capabilities, planned to be delivered with the 2502 release and beyond. ABAP AI is important to all SAP business software developers. It is our shared treasure that we hold in our hands. Let’s take a moment to elaborate a little while on this statement. </P><P style=" text-align : justify; "><FONT size="6"><STRONG>ABAP AI is powerful</STRONG></FONT></P><P style=" text-align : justify; ">The new Joule copilot integrated into ABAP Development Tools for Eclipse, offers a full-fledged copilot experience and by that revolutionizes the way ABAP developers work. It provides AI support during the development process, significantly accelerating the creation and testing of custom ABAP applications. These groundbreaking developments have already been revealed and demonstrated at SAP TechEd 2024.</P><P style=" text-align : justify; ">Imagine someone sitting next to you and guiding you, to write very good ABAP code. Not too bad, you might say. Now imagine that person complementing you and even starting to write code or to do unit tests for you. You can even discuss with this person and have them explain code you don’t understand.</P><P style=" text-align : justify; ">Let's take a closer look at some of Joule's ABAP developer capabilities.</P><P style=" text-align : justify; "><FONT size="5"><STRONG>Joule for ABAP Code Prediction (Ghost Texting)</STRONG></FONT></P><P style=" text-align : justify; ">This feature helps you code. As you start typing your code, Ghost Text uses AI to propose the next lines of code. The difference between classic code completion already available in der development tools and this new feature is that ABAP AI actually understands the context and makes intelligent suggestions that are aligned with your coding objective. This is made possible by GenAI and SAPs trained ABAP model, which is designed to understand and predict ABAP coding patterns. This allows you to spend even more time solving complex problems and innovating.</P><P style=" text-align : justify; "><FONT size="5"><STRONG>ABAP AI Unit Agent</STRONG></FONT></P><P style=" text-align : justify; ">The ABAP AI Unit Agent is designed to assist you generate unit tests for an ABAP class. This ensures that your code is thoroughly tested. Traditionally, you would have to write unit tests manually, which is time-consuming and likely to be error-prone. With the ABAP AI Unit Agent, you can automate this process: You run the unit test for the ABAP class and check the code coverage option. The ABAP Unit Test analyzes the code coverage and identifies the methods that are not adequately covered. The ABAP AI Unit Agent adds to this the generation of unit tests.</P><P style=" text-align : justify; "><FONT size="5"><STRONG>ABAP and Core Data Services Code Explain </STRONG></FONT></P><P style=" text-align : justify; ">This feature makes ABAP, including ABAP Core Data Services (CDS), easier for developers to understand. When you select an ABAP class, CDS view, function module, a method or a code snippet, ABAP & CDS Explain analyzes the code and generates a human-readable explanation. This explanation includes a high-level overview of what the code does, as well as detailed explanations of each component. It is designed to understand ABAP coding patterns and conventions, so that it can provide accurate and useful explanations. By providing clear explanations of complex function modules, it helps developers improve their understanding of ABAP coding patterns, and best practices.</P><P style=" text-align : justify; "><FONT size="6"><STRONG>ABAP AI is attractive</STRONG></FONT><BR />SAPs ABAP AI SDK, powered by Intelligent Scenario Lifecycle Management (ISLM ), serves as an "AI toolbox" for ABAP developers. It allows you to incorporate AI capabilities to your custom ABAP applications. The ABAP AI SDK integrates seamlessly with the SAP BTP GenAI Hub, enabling you to leverage Large Language Models (LLMs) and infuse AI capabilities into your custom applications. This SDK is also used internally for all ABAP-based AI solutions.</P><P style=" text-align : justify; ">With the ABAP AI SDK, you can easily access and use the models and features provided by the Hub by calling released ABAP classes and interfaces directly in your application code. The ABAP AI SDK takes care of the rest, executing prompts and handling the complexities of integrating AI capabilities into ABAP. This seamless integration significantly simplifies the process of incorporating AI into business applications. If that is not attractive, what is?</P><P style=" text-align : justify; "><FONT size="6"><STRONG>ABAP AI is a treasure</STRONG></FONT></P><P style=" text-align : justify; ">Even more powerful than the ABAP AI developer use cases mentioned above is the ABAP custom code migration use case. Our shared goal is to help our customers and partners to transform their custom code and move into SAP’s cloud universe.</P><P style=" text-align : justify; ">ABAP AI for Custom Code Migration will be a game changer in achieving this goal.</P><P style=" text-align : justify; ">We will help you transform your custom code by accelerating the transformation of custom code. Whether it's the mandatory transformation of ABAP code when migrating from ECC to SAP S/4HANA or the subsequent transformation of ABAP code to ABAP Cloud and a Clean Core.</P><P style=" text-align : justify; ">ABAP AI support is provided for the migration of from the classic business suite to SAP S/4HANA and to ABAP Cloud and a Clean Core. This will include explanations of the mandatory simplification items to be considered during your SAP S/4HANA transformation, as well as code suggestions for refactoring your classic ABAP code towards ABAP Cloud. The corresponding AI features will be integrated in the Custom Code Migration App as well as in ABAP Development Tools for Eclipse.</P><P style=" text-align : justify; ">Let us summarize: <STRONG>ABAP AI is</STRONG> <STRONG>powerful</STRONG>. <STRONG>ABAP AI is</STRONG> <STRONG>attractive</STRONG>. <STRONG>ABAP AI is a treasure</STRONG>.</P><P style=" text-align : justify; "> </P><P style=" text-align : justify; ">Have a look at the ABAP AI roadmap for more information:<BR /><SPAN><A href="https://help.sap.com/docs/abap-cross-product/roadmap-info/genai" target="_blank" rel="noopener noreferrer">https://help.sap.com/docs/abap-cross-product/roadmap-info/genai</A></SPAN></P>2024-11-25T08:44:38.882000+01:00https://community.sap.com/t5/technology-blogs-by-sap/best-practices-for-sap-btp-abap-environment/ba-p/13948521Best Practices for SAP BTP ABAP Environment2024-12-18T11:38:59.199000+01:00Nora_Klemphttps://community.sap.com/t5/user/viewprofilepage/user-id/1641196<H1 id="toc-hId-946739386"><STRONG><SPAN class=""><SPAN class="">Best Practices: SAP BTP ABAP Environment</SPAN></SPAN></STRONG></H1><P><STRONG><SPAN class=""><SPAN class="">Introduction: </SPAN></SPAN></STRONG></P><P><SPAN>This blog post summarizes the best practices for getting started with the <A href="https://www.sap.com/products/technology-platform/abap.html" target="_blank" rel="noopener noreferrer">SAP BTP ABAP environment</A> (aka Steampunk). Further articles and blog posts are linked in the appropriate places so that more information is available there if required. </SPAN><SPAN> </SPAN></P><P>The SAP BTP ABAP environment was developed to create cloud-enabled business applications, services and extensions. It offers the ABAP cloud development model that uses SAP HANA Cloud, SAP Fiori and a cloud-optimized ABAP language with standard APIs. Developers can use a toolset for tight integration with Git-enabled lifecycle management. </P><P>The use of SAP BTP ABAP environment offers 3 key benefits:</P><UL><LI>It enables a side-by-side extension option for the custom extension of SAP S/4HANA</LI><LI>The cloud transformation can be accelerated by using reusable ABAP assets to create innovative solutions for the cloud</LI><LI>Keep the core clean, the on-premise custom code is kept on another decoupled platform, where you can profit from independent and regular release cycles</LI></UL><P>The following graphic shows the four different areas of use of the SAP BTP ABAP environment. Individual adaptations for each interest group are possible for each part so that the best possible benefit is achieved. </P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="SAP BTP ABAP Environment Positioning" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/202965i9BF329B37B01601A/image-size/large?v=v2&px=999" role="button" title="Screenshot 2024-12-18 at 07.54.44.png" alt="SAP BTP ABAP Environment Positioning" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">SAP BTP ABAP Environment Positioning</span></span></P><P><STRONG>Development</STRONG></P><P>You can simply connect the ABAP Cloud system to Eclipse so that you can use the <A href="https://help.sap.com/docs/btp/sap-business-technology-platform/eclipse-tool-for-abap-environment" target="_blank" rel="noopener noreferrer">ABAP Development Tools</A> (ADT) provided there to develop the ABAP Cloud apps. <SPAN>Build your own OData services using the <A href="https://pages.community.sap.com/topics/abap/rap" target="_blank" rel="noopener noreferrer">ABAP RESTful application programming model (RAP)</A> optimized for SAP HANA Cloud. You can also analyze ABAP code with advanced static custom code analysis tools like ABAP Test Cockpit, see also the blog <A title="https://community.sap.com/t5/technology-blogs-by-sap/usage-of-abap-test-cockpit-atc-for-developments-in-sap-btp-abap-environment/ba-p/13575890" href="https://community.sap.com/t5/technology-blogs-by-sap/usage-of-abap-test-cockpit-atc-for-developments-in-sap-btp-abap-environment/ba-p/13575890" target="_blank">Usage of ABAP Test Cockpit for developments in SAP BTP ABAP Environment</A>. By the way, the security checks by SAP CVA (Code Vulnerability Analyzer) can be used in SAP BTP ABAP environment without any additional licensing fee.</SPAN></P><P><STRONG><SPAN>Central ABAP Test Cockpit</SPAN></STRONG><SPAN> <STRONG>for Management of Private Cloud and on-premise Systems</STRONG></SPAN></P><P><SPAN>Using central ABAP Test Cockpit (ATC ) in SAP BTP ABAP Environment you can perform remote static code analysis with the latest checks for developments in your private cloud and on-premise systems. Also in this scenario the security SAP CVA checks can be used without any additional licensing fee.</SPAN></P><P><SPAN>See the blog post <A href="https://community.sap.com/t5/technology-blogs-by-sap/usage-of-abap-test-cockpit-atc-in-the-cloud-for-on-premise-developments/ba-p/13576887" target="_blank">Usage of ATC in the cloud for on premise developments</A> for more details. The Custom Code Migration app in SAP BTP ABAP environment can be used to analyze your custom code during conversion to SAP S/4HANA, migration to SAP BTP ABAP environment or during clean core journey.</SPAN></P><P><STRONG>Administration and Integration</STRONG></P><P>Administrative tasks such as user management and security setup can be performed via the role-based SAP Fiori Launchpad. <SPAN>Create extension projects between ABAP Cloud and other SAP Build tools, and easily integrate with existing on-premises systems and any SAP S/4HANA systems. You can also use third-party services that are based on HTTP. </SPAN></P><P><SPAN>The central aspect of the SAP BTP ABAP environment is the broad range of data centers globally provided. You can choose from a total number of more than 20 data centers, a list of all of them can be found in the </SPAN><A href="https://discovery-center.cloud.sap/protected/index.html#/serviceCatalog/abap-environment?region=all&tab=" target="_blank" rel="noopener nofollow noreferrer">SAP Discovery Center</A><SPAN>. The number and therefore the variety will continue to increase, and further locations are planned and will soon be available.</SPAN><SPAN> All other upcoming features can be found in the <A href="https://help.sap.com/docs/abap-cross-product/roadmap-info/sap-btp-abap-environment-roadmap-information?profile=20034788" target="_blank" rel="noopener noreferrer">roadmap</A> and the <A href="https://help.sap.com/whats-new/7a822d3bcaa74f31b98fa315601e9c96?Version=ABAP+Environment+2411&locale=en-US" target="_blank" rel="noopener noreferrer">what's new page</A> for the SAP BTP ABAP environment in the SAP Help Portal. In addition, there is already a <A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-btp-abap-environment-maintenance-windows-and-major-upgrade-windows-in/ba-p/13920833" target="_blank">blog post</A> in which the upgrade window for next year's releases is listed and you can find information regarding the Cloud System Notification Subscriptions (CSNS).</SPAN></P><P><SPAN>The </SPAN><A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/landscape-portal" target="_blank" rel="noopener noreferrer"><SPAN>Landscape Portal</SPAN></A><SPAN> </SPAN><SPAN>is part of the SAP BTP ABAP environment offering and acts as a central tool to perform system administration (for example system hibernation), manage lifecycle operations, and facilitate the configuration and deployment of multitenant SaaS solutions. </SPAN><SPAN> </SPAN></P><P><STRONG><SPAN class=""><SPAN class="">Choosing Your Starting Point: </SPAN><SPAN class="">The Free Tier </SPAN><SPAN class="">Option</SPAN></SPAN><SPAN class=""> </SPAN></STRONG></P><P><SPAN>It is important to note at the initial stage that it is not necessary to create all the systems at once, but only those that are needed at the time. On the one hand, this ensures clarity and, on the other, saves unnecessary costs. </SPAN><SPAN> </SPAN></P><P><SPAN>We recommend using the </SPAN><A href="https://community.sap.com/t5/technology-blogs-by-sap/get-started-with-sap-btp-abap-environment-trial-account-vs-free-tier-option/ba-p/13663694" target="_blank"><SPAN>Free Tier option</SPAN></A><SPAN> for your first contact with this system. This allows you to try out everything free of charge and then decide whether you want to continue using it. This offer can be used for a maximum of 90 days.</SPAN><SPAN> </SPAN></P><P><STRONG><SPAN class=""><SPAN class="">Setting Up Your System: Step-by-Step Guide</SPAN></SPAN><SPAN class=""> </SPAN></STRONG></P><P><SPAN>The next step is the creation of a software component as a delivery unit for your project, this is possible via the SAP Fiori Launchpad. The free tier system can be converted into a standard plan development system, so that all projects and created files can be transferred. It is of course also possible to create a development system directly. The <A href="https://help.sap.com/docs/btp/sap-business-technology-platform/account-administration-in-cockpit?q=btp+cockpit" target="_blank" rel="noopener noreferrer">SAP BTP Cockpit</A> is generally used for the system creation.</SPAN><SPAN> </SPAN></P><P><SPAN>With the <A href="https://help.sap.com/docs/btp/sap-business-technology-platform/eclipse-tool-for-abap-environment" target="_blank" rel="noopener noreferrer">ABAP Development Tools</A> (ADT) for Eclipse, all items can be developed as usual and released using the transport requests.</SPAN><SPAN> </SPAN></P><P><SPAN>Once development is complete, a test system can be created via the SAP BTP Cockpit. The software components can then be pulled into the test system in the SAP Fiori Launchpad.</SPAN><SPAN> </SPAN></P><P><STRONG><SPAN class=""><SPAN class="">Best Practices for System Management </SPAN></SPAN><SPAN class=""> </SPAN></STRONG></P><P><SPAN>A subaccount to create a system is required. We recommend creating a separate subaccount for each system. This ensures maximum flexibility, for example with the trust settings. But there are also scenarios to create multiple systems in one subaccount in order to share the same trust settings. </SPAN><SPAN>All information about Cloud Foundry and the required accounts and spaces can be found in the <A href="https://help.sap.com/docs/btp/sap-business-technology-platform/getting-started-in-cloud-foundry-environment" target="_blank" rel="noopener noreferrer">SAP Help Portal</A>. </SPAN></P><P><SPAN>When creating the subaccount, you can also specify the region in which the system will be located. There are three different hyperscalers to choose from, which are represented in more than 20 data centers worldwide.</SPAN><SPAN> </SPAN></P><P><SPAN>And each system must be assigned to a Cloud Foundry Space. Here too, it is recommended to use a Cloud Foundry Space for only one system to create a better overview.</SPAN><SPAN> </SPAN></P><P><STRONG><SPAN class=""><SPAN class="">Optimizing Costs: Sizing and Hibernation Tips </SPAN></SPAN><SPAN class=""> </SPAN></STRONG></P><P><SPAN>All systems should initially be created with the minimum size, one ACU (ABAP Compute Unit) and 2 HCUs (HANA Compute Unit). This usually provides sufficient coverage, as one ACU can serve around 1,000 active business users per day. These are the only two metrics that are relevant for this. The size can of course be easily changed and adapted at a later stage vie the SAP BTP Cockpit. An overview of the prices can be found in the <A href="https://discovery-center.cloud.sap/protected/index.html#/serviceCatalog/abap-environment?region=all&tab=service_plan" target="_blank" rel="noopener nofollow noreferrer">SAP Discovery Center</A>, where the ACUs and HCUs are also explained in more detail. </SPAN></P><P><SPAN>If the system has more than just the minimum size available, it is possible to use the <A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-btp-abap-environment-elastic-scaling-of-application-servers/ba-p/13614903" target="_blank">elastic scaling</A>. The resources are adjusted and automatically scaled based on the required workload. To be able to use this functionality, the BTPEA Commercial Model is required.</SPAN><SPAN> </SPAN></P><P><SPAN>The default setting when creating a system is a development system, but if you want to create a test or productive system, you must uncheck this box. To distinguish between the different systems, you can assign them a descriptive ID in the “ABAP System ID” field.</SPAN><SPAN> </SPAN></P><P><SPAN>The system hibernation function can be used to save further costs. This function is suitable for stopping development systems outside working hours, for example at weekends, starting test systems only when they are needed or starting the productive system only when it goes live. It can simply be started up via the Landscape Portal.</SPAN><SPAN> </SPAN></P><P><SPAN>A detailed cost analysis for customers can be found in this </SPAN><A href="https://community.sap.com/t5/technology-blogs-by-sap/optimize-your-sap-btp-abap-environment-budget-a-detailed-cost-analysis-for/ba-p/13574333" target="_blank"><SPAN>blog post</SPAN></A><SPAN>.</SPAN><SPAN> </SPAN></P><P><STRONG><SPAN class=""><SPAN class="">Recommended System Landscapes: Finding the Right Fit</SPAN></SPAN><SPAN class=""> </SPAN></STRONG></P><P><SPAN>The various landscapes are only briefly explained here, detailed descriptions can be found in the </SPAN><A href="https://help.sap.com/docs/sap-btp-abap-environment/abap-environment/use-case-1-one-codeline-in-3-system-landscape" target="_blank" rel="noopener noreferrer"><SPAN>documentation</SPAN></A><SPAN>.</SPAN><SPAN> When setting up the systems, we recommend that you only start with the system that is currently required. It is not necessary to set up the entire system landscape directly. It is sufficient if only the development system is set up first and then the test or production system as soon as the need is met. On the one hand, this provides a better overview at the beginning and on the other hand, costs can be reduced. </SPAN></P><P><U>3-System Landscape </U></P><P><SPAN class=""><SPAN class="">This landscape consists of a development system, a quality assurance </SPAN><SPAN class="">system</SPAN><SPAN class=""> and the production system. This allows the tests of new developments to be tested directly in parallel and ensures that the application is also executable in non-development systems.</SPAN></SPAN><SPAN class=""> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Nora_Klemp_0-1732606786963.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/195501i7CD031C779C10044/image-size/medium?v=v2&px=400" role="button" title="Nora_Klemp_0-1732606786963.png" alt="Nora_Klemp_0-1732606786963.png" /></span></P><P><U>5 System Landscape </U></P><P><SPAN>In this scenario, the code lines for development and corrections can be handled separately. The correction system and the test system are on the same level as the production system. This means that the respective corrections can be tested before they are imported into the production system. To develop larger releases and code parts, there is an actual development system. There is also the corresponding test system. Urgent corrections can be implemented directly and have no influence on the normal development cycle.</SPAN><SPAN> </SPAN></P><P><SPAN><U>Note</U>: At this point you can use the system hibernation function, because if it is not necessary to enter corrections frequently, the correction system and the associated test system can be shut down and thus also save costs. If there is a need for these systems, they can simply be started up again. </SPAN><SPAN>A detailed explanation of the system hibernation can be found in this </SPAN><SPAN><A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-btp-abap-environment-manage-system-hibernation/ba-p/13566169" target="_blank">blog post</A>.</SPAN><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Nora_Klemp_1-1732606905002.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/195502i3E8FEF613E88C435/image-size/large?v=v2&px=999" role="button" title="Nora_Klemp_1-1732606905002.png" alt="Nora_Klemp_1-1732606905002.png" /></span></P><P><SPAN>This <A href="https://learning.sap.com/learning-journeys/setting-up-an-abap-environment-on-sap-btp" target="_blank" rel="noopener noreferrer">learning journey</A> can give you an overview of how to create an ABAP environment on the SAP BTP or you can attend our monthly Customer and Partner Roundtable. Among other topics, new product features are presented in this meeting, live demos are shown by experts or you have the opportunity to ask questions live. To register for the roundtable, please follow the <A href="https://community.sap.com/t5/c-khhcw49343/SAP+BTP%25252C+ABAP+environment/pd-p/73555000100800001164" target="_blank">SAP Community for SAP BTP ABAP Environment</A>, where the next date will be announced in a blog post and registration details will be provided. If you have missed a roundtable or would like to look at past ones again, you can find them on <A href="https://github.com/iwonahahn/SAP-BTP-ABAP-Environment-Roundtable/blob/main/README.md#roundtable-15---2024-08-22" target="_blank" rel="noopener nofollow noreferrer">GitHub</A>, where the respective slides are also available. </SPAN></P><P><SPAN>Hopefully this blog post has given you a clear introduction to the SAP BTP ABAP environment. </SPAN></P>2024-12-18T11:38:59.199000+01:00https://community.sap.com/t5/technology-blogs-by-members/how-to-call-rfc-fm-using-service-consumption-model-in-abap-cloud/ba-p/13967139How to call RFC FM using Service Consumption Model in ABAP Cloud2024-12-18T12:02:46.438000+01:00Jamanhttps://community.sap.com/t5/user/viewprofilepage/user-id/151556<P> </P><P>Please follow the below step by step instructions.</P><OL><LI>**Download RFC Metadata**:</LI></OL><P> - Open transaction ACO_PROXY on your ERP ex: S4HANA-on premise system.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Jaman_0-1734519346331.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/203210i366B6D6CA0B7ED61/image-size/medium?v=v2&px=400" role="button" title="Jaman_0-1734519346331.png" alt="Jaman_0-1734519346331.png" /></span></P><P> </P><P>Click on Create(F8) and save the metadata file locally.</P><OL><LI>**Create Service Consumption Model**:</LI></OL><P> - In ADT, create a service consumption model.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Jaman_1-1734519346332.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/203208iA9AF39CF7F837FC6/image-size/medium?v=v2&px=400" role="button" title="Jaman_1-1734519346332.png" alt="Jaman_1-1734519346332.png" /></span></P><P> - Select RFC as the service type and upload the previously downloaded metadata file.</P><P> - Follow the wizard to finalize creation.</P><OL><LI>**Set Up Outbound Service and Communication Scenario**:</LI></OL><P> - Create an outbound service with the type RFC.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Jaman_2-1734519346334.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/203209i7FE916223ABAC8B1/image-size/medium?v=v2&px=400" role="button" title="Jaman_2-1734519346334.png" alt="Jaman_2-1734519346334.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Jaman_4-1734519346340.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/203212iDB4448BC2D150DEA/image-size/medium?v=v2&px=400" role="button" title="Jaman_4-1734519346340.png" alt="Jaman_4-1734519346340.png" /></span></P><P> </P><P>- Create a communication scenario.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Jaman_12-1734519478429.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/203219i4A9655201A6914F0/image-size/medium?v=v2&px=400" role="button" title="Jaman_12-1734519478429.png" alt="Jaman_12-1734519478429.png" /></span></P><P> - And in the outbound service tab, add the outbound service which is just created.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Jaman_13-1734519520805.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/203221i2A78B403595E3136/image-size/medium?v=v2&px=400" role="button" title="Jaman_13-1734519520805.png" alt="Jaman_13-1734519520805.png" /></span></P><P>And Publish the communication scenario.</P><OL><LI>**Administrator Configuration**:</LI></OL><P> - Configure the communication system:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Jaman_14-1734519541491.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/203222iFAE522AB297505BE/image-size/medium?v=v2&px=400" role="button" title="Jaman_14-1734519541491.png" alt="Jaman_14-1734519541491.png" /></span></P><P> </P><P> - Set up the communication arrangement:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Jaman_15-1734519559385.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/203224iCE747BBE26683535/image-size/medium?v=v2&px=400" role="button" title="Jaman_15-1734519559385.png" alt="Jaman_15-1734519559385.png" /></span></P><P> </P><OL><LI>**Call RFC Module in ADT Class Runner**:</LI></OL><P> - Create a new ABAP class implementing IF_OO_ADT_CLASSRUN.</P><P> - Copy the code from Service Consumption Model.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Jaman_16-1734519574084.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/203225iA639063C915D767C/image-size/medium?v=v2&px=400" role="button" title="Jaman_16-1734519574084.png" alt="Jaman_16-1734519574084.png" /></span></P><P> </P><P> - Save and run the class to test the RFC call.</P><P> </P><DIV class=""><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Jaman_0-1734525166430.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/203314iE9DC1A61C4194143/image-size/medium?v=v2&px=400" role="button" title="Jaman_0-1734525166430.png" alt="Jaman_0-1734525166430.png" /></span><P> </P></DIV><P>Thanks,</P><P>Jaman</P><P> </P>2024-12-18T12:02:46.438000+01:00https://community.sap.com/t5/technology-blogs-by-sap/cds-how-to-define-analytical-query-using-two-structures/ba-p/13960195CDS : How to define analytical query using two structures2024-12-20T14:44:22.867000+01:00LinaRauthttps://community.sap.com/t5/user/viewprofilepage/user-id/179963<P>This blog is about how to use two structures in CDS analytical query as in BW query.</P><P>The structure forms the foundational layout of the axes (rows or columns) in a data table, determining how information is organized and presented.<BR />Structural components of key figure structures are always based on the key figure selections (basic key figures, restricted key figures, and calculated key figures). Characteristic structural components cannot contain key figure selections.</P><P><SPAN>The arrangement of the structure affects the order and quantity of key figures or characteristics displayed in the rows and columns of a query or report.</SPAN></P><P><STRONG>Example:</STRONG> BW Query with Characteristic structure and Key Figure structure</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="LinaRaut_0-1733840825806.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/200347i1F98FC24B75D30C2/image-size/large?v=v2&px=999" role="button" title="LinaRaut_0-1733840825806.png" alt="LinaRaut_0-1733840825806.png" /></span></P><P>In Analytical query, elements can be assigned to characteristics structure using @AnalyticsDetails.query.onCharacteristicStructure: true. Element with measures get automatically assigned to measure structure.</P><P>Formulas can be defined for both characteristic structure and measure structure. The operands of a formula must be elements of the same structure to which the formula belongs. Operands of the other structure are not allowed.</P><P>If an analytical query has two structures (a measure and a characteristic structure), then the query result is a grid. Each cell in this grid is defined by an element of the measure structure and one of the characteristic structures. Restrictions are combined with AND. If both elements are formulas, the formula of the measure structure is calculated by default. Also, other properties like scaling, decimals are taken from the element of the measure structure by default. If this should be different, @AnalyticsDetails.query.collisionHandling annotation is used.</P><P> collisionHandling<STRONG>:</STRONG></P><P> <STRONG>{</STRONG> formula <STRONG>:</STRONG> String<STRONG>(</STRONG> 20<STRONG>)</STRONG> <STRONG>enum</STRONG> <STRONG>{</STRONG> DEFAULT<STRONG>;</STRONG> THIS<STRONG>;</STRONG> CONCURRENT<STRONG>;</STRONG> <STRONG>};</STRONG></P><P> decimals <STRONG>:</STRONG> String<STRONG>(</STRONG> 20<STRONG>)</STRONG> <STRONG>enum</STRONG> <STRONG>{</STRONG> DEFAULT<STRONG>;</STRONG> THIS<STRONG>;</STRONG> CONCURRENT<STRONG>;</STRONG> <STRONG>};</STRONG></P><P> scaling <STRONG>:</STRONG> String<STRONG>(</STRONG> 20<STRONG>)</STRONG> <STRONG>enum</STRONG> <STRONG>{</STRONG> DEFAULT<STRONG>;</STRONG> THIS<STRONG>;</STRONG> CONCURRENT<STRONG>;</STRONG> <STRONG>};</STRONG></P><P> semanticObject <STRONG>:</STRONG> String<STRONG>(</STRONG> 20<STRONG>)</STRONG> <STRONG>enum</STRONG> <STRONG>{</STRONG> DEFAULT<STRONG>;</STRONG> THIS<STRONG>;</STRONG> CONCURRENT<STRONG>;</STRONG> <STRONG>};</STRONG></P><P> <STRONG>};</STRONG></P><P><STRONG>Example:</STRONG></P><P> </P><pre class="lia-code-sample language-abap"><code>@AccessControl.authorizationCheck: #NOT_ALLOWED
@EndUserText.label: 'CDS Query with 2 Structures'
@ObjectModel.modelingPattern: #ANALYTICAL_QUERY
@ObjectModel.supportedCapabilities: [ #ANALYTICAL_QUERY ]
define transient view entity ZLR_2STRUCT_CELL_REF_SIMPLE
provider contract analytical_query
as projection on ZOQ_FLIGHT
{
//----Elements of Key Figure structure
@AnalyticsDetails.query.axis: #ROWS
@EndUserText.label: 'Max Capacity Economy'
seatsmax,
@AnalyticsDetails.query.axis: #ROWS
@EndUserText.label: 'Occupied Economy'
seatsocc,
@AnalyticsDetails.query.axis: #ROWS
@Aggregation.default: #FORMULA
@EndUserText.label: 'Percentage'
@AnalyticsDetails.query.decimals: 5
seatsocc / seatsmax * 100 as percentage,
//---Elements of Characteristics Structure
@AnalyticsDetails.query.axis: #COLUMNS
@EndUserText.label: 'Calender Year 2019'
@AnalyticsDetails.query.onCharacteristicStructure: true
case when flyear = '2019' then 1 else null end as year2019,
@AnalyticsDetails.query.axis: #COLUMNS
@EndUserText.label: 'Calender Year 2020'
@AnalyticsDetails.query.onCharacteristicStructure: true
case when flyear = '2020' then 1 else null end as year2020,
@AnalyticsDetails.query.axis: #COLUMNS
@Aggregation.default: #FORMULA
@EndUserText.label: 'Diffenece 2019-2020'
@AnalyticsDetails.query.onCharacteristicStructure: true
@AnalyticsDetails.query.decimals: 2
@AnalyticsDetails.query.collisionHandling: {decimals: #THIS}
$projection.year2019 - $projection.year2020 as difference
}</code></pre><P> </P><P><STRONG>Output:</STRONG><STRONG> </STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="LinaRaut_0-1733840939495.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/200349i4B1D71B8375BDAD2/image-size/large?v=v2&px=999" role="button" title="LinaRaut_0-1733840939495.png" alt="LinaRaut_0-1733840939495.png" /></span></P><P>To display structure element in a hierarchy, AnalyticsDetials.query.elementHierarchy.parent and @AnalyticsDetails.query.elementHierarchy.initiallyCollapsed annotations are used in CDS.</P><P><STRONG>Example:</STRONG></P><P> </P><pre class="lia-code-sample language-abap"><code>@AccessControl.authorizationCheck: #NOT_ALLOWED
@EndUserText.label: 'CDS Query with 2 Structures'
@ObjectModel.modelingPattern: #ANALYTICAL_QUERY
@ObjectModel.supportedCapabilities: [ #ANALYTICAL_QUERY ]
define transient view entity ZLR_2STRUCT_CELL_REF_HIER
provider contract analytical_query
as projection on ZOQ_FLIGHT
{
//----Elements of Key Figure structure
@AnalyticsDetails.query.axis: #ROWS
@EndUserText.label: 'Max Capacity Economy'
seatsmax,
@AnalyticsDetails.query.axis: #ROWS
@EndUserText.label: 'Occupied Economy'
seatsocc,
@AnalyticsDetails.query.axis: #ROWS
@Aggregation.default: #FORMULA
@EndUserText.label: 'Percentage'
@AnalyticsDetails.query.decimals: 5
seatsocc / seatsmax * 100 as percentage,
//---Elements of Characteristics Structure
@AnalyticsDetails.query.axis: #COLUMNS
@EndUserText.label: 'Calender Year 2019'
@AnalyticsDetails.query.onCharacteristicStructure: true
@AnalyticsDetails.query.elementHierarchy.parent: 'difference'
case when flyear = '2019' then 1 else null end as year2019,
@AnalyticsDetails.query.axis: #COLUMNS
@EndUserText.label: 'Calender Year 2020'
@AnalyticsDetails.query.onCharacteristicStructure: true
@AnalyticsDetails.query.elementHierarchy.parent: 'difference'
case when flyear = '2020' then 1 else null end as year2020,
@AnalyticsDetails.query.axis: #COLUMNS
@Aggregation.default: #FORMULA
@EndUserText.label: 'Diffenece 2019-2020'
@AnalyticsDetails.query.onCharacteristicStructure: true
@AnalyticsDetails.query.decimals: 2
@AnalyticsDetails.query.collisionHandling: {decimals: #THIS}
@AnalyticsDetails.query.elementHierarchy.initiallyCollapsed: true
$projection.year2019 - $projection.year2020 as difference
}</code></pre><P> </P><P><STRONG>Output:</STRONG><STRONG> </STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="LinaRaut_0-1733841400499.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/200350iEACEA12DD6E36CDA/image-size/large?v=v2&px=999" role="button" title="LinaRaut_0-1733841400499.png" alt="LinaRaut_0-1733841400499.png" /></span></P><P> </P><P>After Expanding Hierarchy</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="LinaRaut_1-1733841400500.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/200351i346EDC9E54E35CC4/image-size/large?v=v2&px=999" role="button" title="LinaRaut_1-1733841400500.png" alt="LinaRaut_1-1733841400500.png" /></span></P><P><STRONG>Reference:</STRONG></P><P><A href="https://help.sap.com/doc/saphelp_nw73ehp1/7.31.19/en-US/46/81fc706a23468ce10000000a114a6b/content.htm?no_cache=true" target="_blank" rel="noopener noreferrer">Working with Structures</A></P>2024-12-20T14:44:22.867000+01:00https://community.sap.com/t5/technology-blogs-by-sap/transforming-classic-abap-to-abap-cloud-from-background-jobs-to-application/ba-p/13969515Transforming Classic ABAP to ABAP Cloud: From Background Jobs to Application Jobs2024-12-30T22:17:50.580000+01:00nikita_tabakovhttps://community.sap.com/t5/user/viewprofilepage/user-id/1396034<H3 id="toc-hId-1206781630"><SPAN>Introduction: The Journey from Classic to Cloud</SPAN></H3><P>In the S/4HANA world, we hear about Clean Core all the time. Most of us also understand why Clean Core is such a great approach. And when we talk about S/4HANA Cloud, the Core is clean by definition.</P><P>However, I can imagine how inconvenient and counterintuitive resolving a general development task can be for a developer experienced in standard ABAP when working in the Cloud or Clean Core environment.</P><P>So, what am I sharing? In this blog, my intention is not to reiterate the principles of Clean Core, nor is it to provide detailed documentation of ABAP Cloud. Instead, I aim to show you an example of what happens when you need to solve a classic task in a new, cloud-ready way.</P><P> </P><H3 id="toc-hId-1010268125"><SPAN>Classic ABAP: The Good, the Bad, and the Background Jobs</SPAN></H3><P>Any experienced ABAP developer knows what background jobs are. We use them all the time, especially when we want to run tasks periodically and automatically in the system.</P><P><SPAN>When we need our custom code to execute periodically, we create a report with the required logic and schedule it as a background job step. You can refer to this</SPAN><SPAN> </SPAN><A href="https://community.sap.com/t5/enterprise-resource-planning-blogs-by-members/sap-background-job-processing/ba-p/13652516" target="_blank"><SPAN>blog</SPAN></A><SPAN> to refresh your memory on how this is done.</SPAN></P><P>There’s no doubt that even as we step into the Cloud and leave many obsolete methods behind, we still need such essential functionality. But wait - reports are not available in the Cloud!</P><P><STRONG>Real life scenarios:</STRONG></P><P style=" padding-left : 30px; ">Imagine this: you are a seasoned SAP developer with several trusty ABAP reports for background usage that have worked perfectly for years. One day, you move to the Cloud, and you can’t take those reports with you!</P><P style=" padding-left : 30px; "><SPAN>Another case: you’re implementing all your developments in a Clean Core way from the beginning. You receive a requirement to code several processes and have them run autonomously in the system (e.g., a periodic data update). You know exactly how to solve it: create a report, schedule it in</SPAN><SPAN> </SPAN><STRONG>SM36</STRONG><SPAN> - but these tools are no longer available. You need a new way.</SPAN></P><P style=" padding-left : 30px; "> </P><H3 id="toc-hId-813754620"><SPAN>The Cloud Awakens: Modernising with ABAP Cloud</SPAN></H3><P>Good news! A new, cloud-ready method exists, and it comes in the beautiful class-based form we love in modern ABAP development.</P><P><STRONG>How to do it, in a nutshell:</STRONG></P><OL><LI><SPAN><STRONG>Terminology Update</STRONG>:</SPAN><SPAN> Instead of “Background Job,” you’ll now deal with an “Application Job.” The transition from SAP GUI to Fiori means the Application Jobs app is now your tool for scheduling. </SPAN><A href="https://fioriappslibrary.hana.ondemand.com/sap/fix/externalViewer/#/detail/Apps('F1240')/S19OP" target="_blank" rel="noopener nofollow noreferrer"><SPAN>Learn more here</SPAN></A><SPAN>.</SPAN></LI><LI><SPAN><STRONG>Code the Business Logic</STRONG>:</SPAN><SPAN> Instead of creating a report, you’ll create a class. To make the class compatible with Application Jobs, add two interfaces: IF_APJ_DT_EXEC_OBJECT and IF_APJ_RT_EXEC_OBJECT. For SAP BTP ABAP Environment, different interfaces apply (see links below).</SPAN></LI><LI><SPAN><STRONG>Register Your Class</STRONG>:</SPAN><SPAN> Register your class for Application Jobs by creating a Job Catalog Entry.</SPAN></LI><LI><SPAN><STRONG>Create a Job Template</STRONG>:</SPAN><SPAN> To create a "variant" of your Job Catalog with prefilled fields, create a Job Template. All these steps are done in Eclipse ADT.</SPAN></LI></OL><P>Once you’re finished, use the Application Jobs Fiori app to schedule a job based on the Job Template.</P><P><STRONG>Profit:</STRONG></P><DIV><TABLE border="0" cellspacing="0" cellpadding="0"><TBODY><TR><TD><P>Old school reports</P></TD><TD><P>-></P></TD><TD><P>Modern class-based implementation</P></TD></TR><TR><TD><P>SAP GUI: SE38, SM36, SM37</P></TD><TD><P>-></P></TD><TD><P>Eclipse native configurations & Application Jobs Fiori app</P></TD></TR><TR><TD><P>Classic development</P></TD><TD><P>-></P></TD><TD><P>Clean Core-compliant development with all its advantages</P></TD></TR><TR><TD><P>S/4HANA On Premise</P></TD><TD><P>-></P></TD><TD><P><SPAN> </SPAN>Any S/4HANA or BTP ABAP Environment</P></TD></TR></TBODY></TABLE></DIV><P>Let's see a real-life example.</P><H3 id="toc-hId-617241115"> </H3><H3 id="toc-hId-420727610"><SPAN>Real-World Example: A Customer's Case</SPAN></H3><P><STRONG>The problem.</STRONG></P><P style=" padding-left : 30px; ">One of my customers relied on a standard Analytical Query built on a complex stack of CDS views and AMDP procedures. The data selection speed was insufficient.</P><P><STRONG>The solution.</STRONG></P><P style=" padding-left : 30px; ">We decided to persist the analytical data daily for quick access. On top of this persisted data, we created a new analytical view for high-performance data selection. To automate this process, we needed a periodic job.</P><P><STRONG>Additional conditions.</STRONG></P><P style=" padding-left : 30px; ">The project strategy required Clean Core implementation.</P><P>Let’s see how this was achieved.</P><H3 id="toc-hId-224214105"> </H3><H3 id="toc-hId-27700600"><SPAN>The How-To: Step-by-Step Guide</SPAN></H3><H5 id="toc-hId-89352533">1. Class with business logic</H5><P>Create an ABAP class for your application job:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="1.png" style="width: 1171px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204122i5EDB8ECB194FD601/image-dimensions/1171x345?v=v2" width="1171" height="345" role="button" title="1.png" alt="1.png" /></span></P><P> </P><P>Define parameters for the Application Job (e.g., using class constants)</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="2.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204123i23CFE916AD2B3BD1/image-size/large?v=v2&px=999" role="button" title="2.png" alt="2.png" /></span></P><P><SPAN>See how this parameters will look like in the Fiori App:</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="3.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204124i30CDE8F5315B74EA/image-size/large?v=v2&px=999" role="button" title="3.png" alt="3.png" /></span></P><P><SPAN>We now need to define what happens, when the Application Job framework calls our class:</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="4.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204125iA8F98FC36516E6E8/image-size/large?v=v2&px=999" role="button" title="4.png" alt="4.png" /></span></P><H5 id="toc-hId--107160972"> </H5><H5 id="toc-hId--303674477">2. Job Catalog</H5><P>We need to create an entry and specify the class for job execution - all in Eclipse ADT:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="5.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204126i157EDCC847ADF98A/image-size/large?v=v2&px=999" role="button" title="5.png" alt="5.png" /></span></P><H5 id="toc-hId--1420390803"> </H5><H5 id="toc-hId--1616904308">3. Job Template</H5><P>Finally, we create a variant for our job. We can add values for some of the parameters:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="6.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204127i9971331A06853380/image-size/large?v=v2&px=999" role="button" title="6.png" alt="6.png" /></span></P><P> </P><P><SPAN>Now we are all set from the development point of view. We can launch the Application Jobs app and create a job.</SPAN> </P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="7.png" style="width: 517px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204134iEDB869780427E6A1/image-dimensions/517x288?v=v2" width="517" height="288" role="button" title="7.png" alt="7.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="8.png" style="width: 504px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204135i2613A051189CA87F/image-dimensions/504x443?v=v2" width="504" height="443" role="button" title="8.png" alt="8.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="9.png" style="width: 492px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204132i36E4ED2BEA63246B/image-dimensions/492x453?v=v2" width="492" height="453" role="button" title="9.png" alt="9.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="10.png" style="width: 485px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/204136iC233E948D11BD970/image-dimensions/485x445?v=v2" width="485" height="445" role="button" title="10.png" alt="10.png" /></span></P><H3 id="toc-hId--1226611799"> </H3><H3 id="toc-hId--1423125304"><SPAN>P.S.</SPAN></H3><P>That’s it! The Application Jobs app includes additional features (e.g., job status monitoring) not covered in this blog. Refer to the official documentation for more.</P><P>For SAP BTP ABAP Environment, updated versions of class interfaces exist. At the time of writing, S/4HANA still uses the older versions.</P><P>This blog isn’t a comprehensive guide to all “Standard ABAP → ABAP Cloud” transformations but demonstrates how familiar concepts can be adapted for the Cloud.</P><P>I hope I’ve shown that there’s no rocket science here!</P><P>So, what’s next? Use this blog as a quick guide for ABAP Application Jobs or as inspiration for ABAP Cloud. Stay tuned for more on tackling challenges in the Classic ABAP → ABAP Cloud journey!</P><H3 id="toc-hId--1619638809"> </H3><H3 id="toc-hId--1816152314">Links</H3><OL><LI><A href="https://help.sap.com/docs/btp/sap-business-technology-platform/application-jobs?locale=en-US" target="_blank" rel="noopener noreferrer"><SPAN>Application</SPAN><SPAN> Jobs in ABAP Environment (BTP) (latest)</SPAN></A></LI><LI><A href="https://help.sap.com/docs/SAP_S4HANA_CLOUD/6aa39f1ac05441e5a23f484f31e477e7/0837d1ea0b0b4d3892f66e8533b654cb.html?locale=en-US&q=application%20job" target="_blank" rel="noopener noreferrer"><SPAN>Application</SPAN><SPAN> Jobs in S/4HANA (latest)</SPAN></A></LI><LI><A href="https://learning.sap.com/learning-journeys/administrating-the-sap-s-4hana-cloud-public-edition/introducing-application-jobs_cf77594e-9dd1-454b-b8d1-05079dfee508" target="_blank" rel="noopener noreferrer"><SPAN>Application Jobs - Learning Journey</SPAN></A></LI></OL>2024-12-30T22:17:50.580000+01:00https://community.sap.com/t5/application-development-blog-posts/sap-developer-news-january-2nd-2025/ba-p/13970764SAP Developer News, January 2nd, 20252025-01-02T21:10:00.075000+01:00thomas_junghttps://community.sap.com/t5/user/viewprofilepage/user-id/139<P><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%2F08c7UqbPlDk%3Ffeature%3Doembed&display_name=YouTube&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D08c7UqbPlDk&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F08c7UqbPlDk%2Fhqdefault.jpg&type=text%2Fhtml&schema=youtube" width="400" height="225" scrolling="no" title="SAP Developer News 2024 Year In Review Part 2" frameborder="0" allow="autoplay; fullscreen; encrypted-media; picture-in-picture;" allowfullscreen="true"></iframe></div></P><P><STRONG>Podcast: </STRONG><A href="https://podcast.opensap.info/sap-developers/2025/01/02/sap-developer-news-january-2nd-2025/" target="_blank" rel="nofollow noopener noreferrer">https://podcast.opensap.info/sap-developers/2025/01/02/sap-developer-news-january-2nd-2025/</A></P><H3 id="toc-hId-1207439108">DESCRIPTION</H3><P>A look back at the year 2024 in the SAP Developer Ecosystem with insights from each of the Developer Advocates.</P><P><STRONG>Year in review: Antonio</STRONG></P><UL><LI><STRONG>What’s new in SAP Integration Suite: </STRONG><A href="https://help.sap.com/whats-new/5793247a5d5741beb0decc5b7dee1160?Environment=Cloud+Foundry&Valid_as_Of=2024-01-01:2024-12-31&locale=en-US" target="_blank" rel="noopener noreferrer">https://help.sap.com/whats-new/5793247a5d5741beb0decc5b7dee1160?Environment=Cloud+Foundry&Valid_as_Of=2024-01-01:2024-12-31&locale=en-US</A></LI></UL><P><STRONG>Year in review: Kevin</STRONG></P><UL><LI><STRONG>CAP-LLM-Codejam: </STRONG><A href="https://github.com/SAP-samples/codejam-cap-llm" target="_blank" rel="nofollow noopener noreferrer"><STRONG>https://github.com/SAP-samples/codejam-cap-llm</STRONG></A></LI></UL><H3 id="toc-hId-1010925603">CHAPTER TITLES</H3><P>0:00 Intro<BR />0:10 Year in review: Antoni<BR />2:28 Year in review: Josh<BR />4:27 Year in review: Sheena<BR />5:51 Year in review: Michelle<BR />7:36 Year in review: Ajay<BR />9:01 Year in review: Kevin<BR />10:08 Year in review: Rich<BR />11:46 Year in review: Daniel</P><H3 id="toc-hId-814412098">Transcription</H3><P><STRONG>[Intro]</STRONG> This is the SAP Developer News for January 2, 2025. Happy New Year!</P><P><STRONG>[Antonio]</STRONG> Hello, SAP Developers! 2024 was a very exciting year in the integration space. Proof of that is that there have been a total of 282 updates in SAP Integration Suite this year alone. There are two new capabilities, the Dataspace and EventMesh capabilities. The integration architecture guide was recently updated. Edge Integration Cell is now supported in more platforms. for example GKE and Red Hat OpenShift. API Business Hub is now known as the developer hub. In cloud integration, we now have design guidelines checks in iFloos. The pipeline lab concept was introduced and it has significantly evolved. Lots of new adapters available for SAP cloud integration and the migration tooling is now pattern -based instead of template base. In the event-driven space, EventMesh is now part of the SAP integration suite. The SAP Event Broker is now known as SAP Cloud Application Event Hub and we can configure their connectivity with cloud integration. We can now leverage the SAP Application Interface framework to send events to advance event mesh and many more updates.</P><P>Personally, I had the opportunity to meet many SAP developers, customers and partners at different in-person events, be it as part of our CodeJams, networking events, SAP Inside Tracks, or Take It On Tour. Definitely the highlight for me there was the CodeJam road show we did with Josh in Latin America. Seuro, organized another in 2025. Virtually, interacting with many via the SAP community. I hosted a Code Challenge focusing on cloud events. I did a few live streams, but not as many as I would like. Also, being part of SAP TechEd Virtual, and also, organizing the Devtoberfest 2024 integration track. Last, presentedly, not least, I got to work on a unique project, which was publishing an SAP Press eBite, focusing on developing event -driven integrations with SAPBTP, published on the 14th of November. What can I say? It was an eventful year, but I'm already looking forward to 2025 and sharing some of the new cool projects we're working on. Ciao.</P><P><STRONG>[Josh]</STRONG> Hey everybody. It's Mr. Bluebeard, Josh Bentley, and I wanted to reach out to you at the end of this holiday season to say, I am not traveling right now. I did a lot of traveling this year, and I was super appreciative of it. And that's really the highlight of what I wanted to say while I'm actually making my bathroom a proper color, blue. So see what's going on there? And we're going to tile the bottom. So it's going to look nice when it's done. That's what I'm doing at the end of the year. Taking a few days off, relaxing, recharging, and reflecting. So the 3Rs, Recharging, Reflecting. I just made that up. I basically am going to sit here and paint, and when I get a little frustrated to have a project's going, I'm going to remember how lucky I am to get to be a developer advocate for SAP, talk about thing like SAP build, and when I'm not building tile or building something in my house, I'm building apps. And I got to do that with Antonio in Latin America, my first time down there. So we got to go to great four different Code Jam locations. We did eight co-GEMs down there and a few stomptish. And then I got to go to Europe, of course, to do tech ed. And then we did Tech Ed on tour in Florida and then jump down to Australia. Also my first time down there. So amazing time getting to be a part of this SAP community. And what's really cool is that I don't care really where the geography is, where it is in the northern hemisphere, the southern, eastern, west. It doesn't matter because it's all about the people. It's about you guys. I got pain on my fingers. It's about you guys, the SAP community. And it doesn't matter where we are, as long as we're together and we're interacting and I can talk to you about code. You can talk to me about code or just what's going on in your life. It's really nice to be a part of this community. So I'm now going to spend the next four hours naming each and every one of you. I've met this. No, just kidding. This is a short two-minute video. I'm going to get back to working here in the house and take off a lot of days the rest of the year. I hope you all have a great holiday season. And I can't wait to see you next year. Bye.</P><P><STRONG>[Sheena]</STRONG> Hello everyone. As 2024 comes to a close, I want to celebrate some of the major milestones I achieved this year. My journey as a developer advocate in 2024 was very exciting. I kicked off the year with an ABAP Cloud CodeJam in Mumbai, followed by several code jams across India alongside my colleague, Shilpa. This year brought me closer to the community through several events like SAP Insight Track, the Abab Developer Challenge, the SAP TechByte series and Devtoberfest. In SAPPTICPi series, we have covered all that you need to know about ABAP data services. In September, September, I had the privilege of organizing the ABAP track for one of the most awaited events, Devtoberfest. It featured many great sessions led by the experts and the response from the community was truly overwhelming. Then in October, I traveled to the beautiful city of Heidelberg, Germany, to participate in my first SAP TechEd virtual event. I got the opportunity. to present a developer keynote session together with my amazing colleagues, Shilpa, Rich and Ritali. It was also a fantastic experience to meet my colleagues from around the globe. I hope your 2024 was equally exciting and let us look forward for even more exciting activities in 2025. Till then, wish you all a Merry Christmas and Happy New Year.</P><P><STRONG>[Michelle]</STRONG> 24 was such a great year as I got to do so many incredible things. and meet incredible people while doing it. I got to go to my childhood dream country of Australia, not just once, but twice, to present and meet all the folks attending the mastering SAP event in April and at the SAUGX conference after TechEd. Everyone there was so friendly and excited about SAP that I would gladly fly the 22 hours it takes to get there every opportunity. I was even able to turn one of those into a two-week vacation to explore beautiful Australia and I got to snorkel at the Great Barrier Reef, which was awesome. I also got to hang out with the amazingly talented and knowledgeable Devtoberfest 2023 winners at the ASUG Tech Connect event in Florida and at Disney World. It was all part of their reward for reaching Nirvana in Devtoberfest last year, and I'm grateful to be such a big part of it. It was so fun to be able to sit down and get to know these folks over a few days and chat all about SAP technologies. It was also fun to go on a roller coaster at Disney, which was not a work perk I ever expected to have. Finally, I being able to have. terrified of heights, was able to jump out of a plane because one of my insanely brave go -workers does it as a hobby. I got to ask him a million questions about it, including if they could push me out of the plane, which didn't end up being a problem because I had the tallest instructor as my tandem buddy, so my feet weren't even touching the plane when we got out.</P><P><STRONG>[Ajay]</STRONG> This year, as an SAP developer advocate was wonderful for me, and these are just a few of the highlights. I got to travel the world, present, and meet wonderful members of our community. I know next year is going to have even more in -person events and I can't wait to meet everyone there and present on topics I'm so passionate about. Happy Holidays, Happy New Year, and as always, happy coding. Hello everyone, Season's greetings. As we approach the new year, let's reflect on the past year. I had the privilege of meeting many of our SAP developer community members during 10 in-person code jam sessions across Kolkata, Kohamvatur, Hyderabad and Bengaluru. I am very grateful to ask for CodeJam hosts for making this in-person event possible. We look forward to reaching more regions and developers next year. I had a person of meeting some of you at SAP Inside Track events where I also presented a session on SAP Cloud Application Programming Model. Later in September and October, we were focused on organizing SAP Devtoberfest event and virtual SAP TechEd. A big thank you to all our Devtoberfest presenters and participants for making it a resounding success. Many of you personally expressed your appreciation for the format and accessibility of Devtoberfest sessions. We hope to make it even better next year. Finally, I got to meet SAP community members and developers at SAUG-X TechEd on tour in Melbourne. It was pleasure to connect with so many of you at Developer Garage, hands-on sessions and mini stamp dish in Australia. Wishing you all, Merry Christmas and a very happy end to the year. and looking forward to seeing you soon next year.</P><P><STRONG>[Kevin]</STRONG> We're in the last months of the year, which to me is always a beautiful time of quietness, learning and reflection. I'm trying to take the time to look back on the year. My son turned one and he learned to speak and I visited my dad in Grandmont, California. But there were a lot of great moments at work as well. For me, what stood out the most was Devtoberfest in Recap. Both events gave me the chance to connect and interact with our development community, the most and I also saw all my colleagues again. I had a great discussion with smart developers and even found some new friends. With SAP's AI portfolio growing rapidly, I've decided to create a brand new CodeJam covering the AI service development with CAP and SAP Charter to the AI Hub, which to me is not only interesting, but also gives you a great opportunity to learn this great new technology. I'm excited to see what the new year brings and I hope I'll see you on one of my co-jams. I wish you all so quiet times, time with family and friends, time to reflect and be mindful. See you all in 2025.</P><P><STRONG>[Rich]</STRONG> Hey folks, Rich I'm in here and I have my best little boy, Sully, and my best little girl, Sage, here with me as well. And of course, my beautiful wife, Shauna behind the camera. Thanks, baby. I just wanted to take a couple minutes and reflect on 2024 and share some of the highlights. from the year. The developer advocates team had a really great year, and we really do appreciate your support, so thank you for that. Some highlights for me. We, of course, did the Code Jam Roadshow through Europe with Thomas, starting, or stopping through Romania, Germany, France, and Spain. It was a really great trip, and we had a chance to talk with so many of you face -to-face was really great. After that, my focus was really on tech-ed planning and supporting Devtoberfest, which was a really great. was an entire team effort. Our team worked closely with internal colleagues to build out a fantastic Devtoberfest agenda and the response from all of you was huge. So thank you for that. And of course, the whole team dropped into Heidelberg to host the TechEd virtual, which was awesome. I had so much fun with everyone involved. The developer keynote deconstructed was dialed in as usual. The Tech Ed on tour stops around the world. The last couple months of the year have been, I was a whirlwind. And I think a lot of us are a little relieved that it's over. So we're resting up and getting ready to do it all again next year, all for you, our developer community. So with that, I leave you with Happy Holidays, Happy New Year, and I'll see you in 2025.</P><P><STRONG>[Daniel]</STRONG> I'm here in Kanandawa along the lake in upstate New York, where it's quite called, I must say. And I just want to look back at 2020. and say it was an amazing year. I got to be all over the world doing code jams at beating all kinds of interesting people and helping you learn SAP build. And I'm looking forward to an amazing 2025 with a dozen more code jams, tech cad, Devtoberfest, and more. And I want to wish all of you an amazing 2025 full of peace and happiness where all your dreams come true. And I finally want to especially thank my colleagues by fellow developers. Advocates who really, really helped me in all kinds of ways. And I want to wish them, I want to wish my fellow developer advocates, a wonderful 2025. We're full of success and excitement and I don't know what to say now. And in 2025, I want to wish all of my developer advocate colleagues who've done so much for me, an amazing year. And I hope we get to work together even. more. Take care. </P>2025-01-02T21:10:00.075000+01:00https://community.sap.com/t5/application-development-blog-posts/etag-in-rap/ba-p/13982291ETag In RAP2025-01-10T14:24:58.475000+01:00Vivek_Sahu_21https://community.sap.com/t5/user/viewprofilepage/user-id/1451075<P><SPAN>This blog post provides a beginner-friendly introduction to the concept of ETags in RAP (RESTful ABAP Programming).</SPAN><SPAN> </SPAN></P><P><FONT size="5"><STRONG><SPAN>Introduction</SPAN></STRONG><SPAN> </SPAN></FONT></P><P><SPAN>This is one of the concurrency control approaches</SPAN><SPAN> </SPAN></P><P><SPAN>ETag is used to manage data concurrency, preventing multiple users from overwriting the same record simultaneously, similar to the functionality of lock objects.</SPAN><SPAN> </SPAN></P><P><SPAN><STRONG>Concurrency:</STRONG> Accessing/Updating a resource at the same time by different users. It causes confusion among the users and inconsistency in the excepted output.</SPAN><SPAN> </SPAN></P><P><SPAN>If you use Etag, so multiple user can only read the data but they can't update the data, because the server first check the Etag value.</SPAN><SPAN> </SPAN></P><P><FONT size="5"><STRONG><SPAN>Scenario for Etag in RAP</SPAN></STRONG></FONT><SPAN> </SPAN></P><P><SPAN>Consider a scenario where two users access the same record, and User 1 saves their changes first, the ETag mechanism ensures User 2 cannot overwrite those changes without being aware of the update. This prevents data inconsistencies. In this blog, we'll explore implementing ETag functionality in RAP using a timestamp field.</SPAN><SPAN> </SPAN></P><P><FONT size="5"><STRONG><SPAN>Procedure:</SPAN></STRONG><SPAN> </SPAN></FONT></P><P><FONT color="#808080"><STRONG><U><I>1. Created one database table ‘ZVS_DT_TRAVEL’.</I></U> </STRONG></FONT></P><P><SPAN>The table </SPAN><SPAN>zvs_dt_travel</SPAN><SPAN> holds information related to travel records. It includes key fields like </SPAN><SPAN>travel_id</SPAN><SPAN>, and non-key fields such as </SPAN><SPAN>agency_id</SPAN><SPAN>, </SPAN><SPAN>begin_date</SPAN><SPAN>, </SPAN><SPAN>end_date</SPAN><SPAN>, </SPAN><SPAN>last_changed_by</SPAN><SPAN>, and </SPAN><SPAN>last_changed_at</SPAN><SPAN>. The field </SPAN><SPAN>last_changed_at</SPAN><SPAN> is particularly important because it tracks the last timestamp when the record was modified. This timestamp will be used to generate the ETag value.</SPAN></P><P> </P><pre class="lia-code-sample language-abap"><code>@EndUserText.label : 'Table for travel'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zvs_dt_travel {
key client : abap.clnt not null;
key travel_id : /dmo/travel_id not null;
agency_id : /dmo/agency_id;
begin_date : /dmo/begin_date;
end_date : /dmo/end_date;
last_changed_by : abp_locinst_lastchange_user;
last_changed_at : abp_locinst_lastchange_tstmpl;
}</code></pre><P> </P><P><FONT color="#808080"><SPAN class=""><SPAN class="">This table holds travel records:</SPAN></SPAN></FONT><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vivek_Sahu_21_0-1736500272017.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210514i544195B380809174/image-size/large?v=v2&px=999" role="button" title="Vivek_Sahu_21_0-1736500272017.png" alt="Vivek_Sahu_21_0-1736500272017.png" /></span></P><P><U><FONT color="#808080"><STRONG><EM>2. <SPAN class=""><SPAN class="">Now create one interface</SPAN> <SPAN class="">view</SPAN><SPAN class=""> ‘ZVS_I_TRAVEL1’</SPAN><SPAN class=""> on top of DB table: -</SPAN></SPAN><SPAN class=""> </SPAN></EM></STRONG></FONT></U></P><P><SPAN>The CDS interface view </SPAN><SPAN>zvs_i_travel1</SPAN><SPAN> selects the relevant fields from the </SPAN><SPAN>zvs_dt_travel</SPAN><SPAN> table, including </SPAN><SPAN>last_changed_at</SPAN><SPAN>. This field (</SPAN><SPAN>last_changed_at</SPAN><SPAN>) will be used for generating the ETag value, as indicated by the </SPAN><SPAN>@Semantics.systemDateTime.localInstanceLastChangedAt</SPAN><SPAN> annotation. This annotation ensures that </SPAN><SPAN>last_changed_at</SPAN><SPAN> is recognized as the field that tracks the last modification time.</SPAN><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vivek_Sahu_21_0-1736500460512.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210516i0B9BCC11173A9600/image-size/large?v=v2&px=999" role="button" title="Vivek_Sahu_21_0-1736500460512.png" alt="Vivek_Sahu_21_0-1736500460512.png" /></span></P><P><STRONG><SPAN>Code of interface view:</SPAN></STRONG><SPAN> </SPAN></P><P> </P><pre class="lia-code-sample language-abap"><code>@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'interface view for travel'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define root view entity zvs_i_travel1 as select from zvs_dt_travel
{
key travel_id as TravelId,
agency_id as AgencyId,
begin_date as BeginDate,
end_date as EndDate,
last_changed_by as LastChangedBy,
@Semantics.systemDateTime.localInstanceLastChangedAt: true //annotation marks LastChangedAt as the timestamp for enabling ETag checks.
last_changed_at as LastChangedAt
}</code></pre><P> </P><UL><LI><STRONG><SPAN>ETag Generation</SPAN></STRONG><SPAN>: The </SPAN><SPAN>last_changed_at</SPAN><SPAN> field will act as the ETag value. The ETag is a unique identifier for the version of the record. Whenever the </SPAN><SPAN>last_changed_at</SPAN><SPAN> value changes (which happens when a record is updated), the ETag value will also change.</SPAN><SPAN> </SPAN></LI></UL><P><STRONG><FONT color="#808080"><U><I>3. Now create on consumption view ‘ZVS_C_TRAVEL1’ on top of interface view:</I></U> </FONT></STRONG></P><P><SPAN>The consumption view </SPAN><SPAN>zvs_c_travel1</SPAN><SPAN> projects the data from the interface view </SPAN><SPAN>zvs_i_travel1</SPAN><SPAN>. This view is intended to expose the data for transactional operations, such as </SPAN><SPAN>create</SPAN><SPAN>, </SPAN><SPAN>update</SPAN><SPAN>, and </SPAN><SPAN>delete</SPAN><SPAN>. The consumption view allows clients to interact with the data, but the actual persistence and behavior are managed through the behavior definition.</SPAN><SPAN> </SPAN></P><P><STRONG><SPAN>Code of Projection view:</SPAN></STRONG><SPAN> </SPAN></P><P> </P><pre class="lia-code-sample language-abap"><code>@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Consumption view for travel'
@Metadata.ignorePropagatedAnnotations: true
@Metadata.allowExtensions: true
define root view entity zvs_c_travel1
provider contract transactional_query
as projection on zvs_i_travel1
{
key TravelId,
AgencyId,
BeginDate,
EndDate,
LastChangedBy,
LastChangedAt
}</code></pre><P> </P><P><U><STRONG><FONT color="#808080"><I>4. Now create a behavior definition on top of interface view:</I></FONT></STRONG> </U></P><P><SPAN>In the behavior definition for </SPAN><SPAN>zvs_i_travel1</SPAN><SPAN>, the </SPAN><SPAN>LastChangedAt</SPAN><SPAN> field is specified as the </SPAN><STRONG><SPAN>ETag</SPAN></STRONG><SPAN> for concurrency control. It is marked as the </SPAN><SPAN>etag master LastChangedAt</SPAN><SPAN>, ensuring that the value of </SPAN><SPAN>LastChangedAt</SPAN><SPAN> will be used for update validation.</SPAN><SPAN> </SPAN></P><UL><LI><STRONG><SPAN>Update Scenario</SPAN></STRONG><SPAN>: When a client sends an </SPAN><SPAN>UPDATE</SPAN><SPAN> request, it must include the </SPAN><SPAN>If-Match</SPAN><SPAN> header containing the </SPAN><SPAN>LastChangedAt</SPAN><SPAN> timestamp (the ETag value). The system will check this value against the current </SPAN><SPAN>LastChangedAt</SPAN><SPAN> value stored in the database. If the values match, the update will proceed. If the values don't match (meaning the record has been updated by another user), the system will return a </SPAN><SPAN>412 Precondition Failed</SPAN><SPAN> error, preventing the overwrite.</SPAN><SPAN> </SPAN></LI></UL><P><STRONG><SPAN>Code of Behavior Definition of Interface:</SPAN></STRONG><SPAN> </SPAN></P><P> </P><pre class="lia-code-sample language-abap"><code>managed implementation in class zbp_vs_i_travel1 unique;
strict ( 2 );
define behavior for zvs_i_travel1 //alias <alias_name>
persistent table zvs_dt_travel
lock master
authorization master ( instance )
etag master LastChangedAt //ensures concurrency control using the LastChangedAt field for ETag verification
{
create;
update;
delete;
field ( readonly ) TravelId;
mapping for zvs_dt_travel{
TravelId = travel_id;
AgencyId = agency_id;
BeginDate = begin_date;
EndDate = end_date;
LastChangedBy = last_changed_by;
LastChangedAt = last_changed_at;
}
}</code></pre><P> </P><P><STRONG><FONT color="#808080"><U><I>5. Now create a behavior definition on top of consumption view:</I></U> </FONT></STRONG></P><P><SPAN>In the behavior definition for the </SPAN><STRONG><SPAN>consumption view</SPAN></STRONG><SPAN> (</SPAN><SPAN>zvs_c_travel1</SPAN><SPAN>), you must specify that </SPAN><STRONG><SPAN>ETag</SPAN></STRONG><SPAN> should be used. This tells RAP that the consumption view will work with ETags when performing operations like create, update, or delete.</SPAN><SPAN> </SPAN></P><UL><LI><STRONG><SPAN>ETag Use</SPAN></STRONG><SPAN>: This line ensures that </SPAN><STRONG><SPAN>ETag</SPAN></STRONG><SPAN> will be used during the </SPAN><SPAN>create</SPAN><SPAN>, </SPAN><SPAN>update</SPAN><SPAN>, and </SPAN><SPAN>delete</SPAN><SPAN> operations. It tells RAP that when a record is updated, the </SPAN><STRONG><SPAN>ETag</SPAN></STRONG><SPAN> value (i.e., </SPAN><SPAN>LastChangedAt</SPAN><SPAN>) should be checked to prevent overwriting concurrent changes.</SPAN><SPAN> </SPAN></LI></UL><P><STRONG><SPAN>Code of Behavior Definition of Projection:</SPAN></STRONG><SPAN> </SPAN></P><P> </P><pre class="lia-code-sample language-abap"><code>projection;
strict ( 2 );
define behavior for zvs_c_travel1 alias travel
use etag //ensures ETag validation during create, update, and delete operations
{
use create;
use update;
use delete;
}</code></pre><P> </P><P><STRONG><SPAN>ETag Mechanism in Updating Data</SPAN></STRONG><SPAN>:</SPAN><SPAN> </SPAN></P><P><SPAN>When the client wants to update the travel record, it sends a </SPAN><SPAN>PATCH</SPAN><SPAN> request to the system with the </SPAN><SPAN>If-Match</SPAN><SPAN> header containing the ETag value (i.e., the </SPAN><SPAN>LastChangedAt</SPAN><SPAN> value). The system will compare the </SPAN><SPAN>If-Match</SPAN><SPAN> value with the current </SPAN><SPAN>LastChangedAt</SPAN><SPAN> value in the database.</SPAN><SPAN> </SPAN></P><UL><LI><SPAN>If the </SPAN><SPAN>If-Match</SPAN><SPAN> value matches the current </SPAN><SPAN>LastChangedAt</SPAN><SPAN>, the update is allowed, and the </SPAN><SPAN>LastChangedAt</SPAN><SPAN> is updated to the current timestamp.</SPAN><SPAN> </SPAN></LI></UL><UL><LI><SPAN>If the </SPAN><SPAN>If-Match</SPAN><SPAN> value doesn't match the current </SPAN><SPAN>LastChangedAt</SPAN><SPAN> (i.e., the record has been modified by another user in the meantime), the update is rejected, and the system returns a </SPAN><SPAN>412 Precondition Failed</SPAN><SPAN> error.</SPAN><SPAN> </SPAN></LI></UL><P><SPAN>Now from the Frontend, two different users are accessing the same data at the same time:</SPAN><SPAN> </SPAN></P><P><FONT color="#808080"><EM>User 1: </EM></FONT></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vivek_Sahu_21_0-1736501048634.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210521i78A31FF53D4FE640/image-size/large?v=v2&px=999" role="button" title="Vivek_Sahu_21_0-1736501048634.png" alt="Vivek_Sahu_21_0-1736501048634.png" /></span></P><P><EM><FONT color="#808080">User 2:</FONT></EM><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vivek_Sahu_21_1-1736501048635.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210520i389F7F7D76B60A2F/image-size/large?v=v2&px=999" role="button" title="Vivek_Sahu_21_1-1736501048635.png" alt="Vivek_Sahu_21_1-1736501048635.png" /></span></P><P><EM>Now user 1 will change the <STRONG>End Date:</STRONG> </EM></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vivek_Sahu_21_2-1736501048636.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210519iE1828D8DCD9FE1ED/image-size/large?v=v2&px=999" role="button" title="Vivek_Sahu_21_2-1736501048636.png" alt="Vivek_Sahu_21_2-1736501048636.png" /></span><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vivek_Sahu_21_3-1736501048637.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210523iC794FA481BAFD354/image-size/large?v=v2&px=999" role="button" title="Vivek_Sahu_21_3-1736501048637.png" alt="Vivek_Sahu_21_3-1736501048637.png" /></span></P><P><EM>Here we can see that User 1 updated the data successfully.</EM></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vivek_Sahu_21_4-1736501048637.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210524i45643D4BD56FB17F/image-size/large?v=v2&px=999" role="button" title="Vivek_Sahu_21_4-1736501048637.png" alt="Vivek_Sahu_21_4-1736501048637.png" /></span></P><P><EM>But here User 2, still viewing the old version (Jan 8, 2025) </EM></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vivek_Sahu_21_5-1736501048638.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210522i4BBC2DD7A67E4CB1/image-size/large?v=v2&px=999" role="button" title="Vivek_Sahu_21_5-1736501048638.png" alt="Vivek_Sahu_21_5-1736501048638.png" /></span></P><P><EM>Now User 2 will change End Date to Aug 5, 2025: </EM></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vivek_Sahu_21_6-1736501048639.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210525i44163E0B87BA4BF0/image-size/large?v=v2&px=999" role="button" title="Vivek_Sahu_21_6-1736501048639.png" alt="Vivek_Sahu_21_6-1736501048639.png" /></span></P><P><EM>So if user 2 click on save button, so he will get one error: - </EM></P><P><SPAN>(Your changes could not be saved. A more recent version is available. To make changes to the latest version, please refresh the data).</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vivek_Sahu_21_7-1736501048639.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210526i049359D0DF8F17BA/image-size/medium?v=v2&px=400" role="button" title="Vivek_Sahu_21_7-1736501048639.png" alt="Vivek_Sahu_21_7-1736501048639.png" /></span></P><P><SPAN>User 2 cannot overwrite User 1's updated record without refreshing to see the latest changes.</SPAN><SPAN> </SPAN></P><P><SPAN>if User 1 updates a record and saves it, User 2, still viewing the old version, cannot overwrite the updated record without refreshing the data. The ETag, generated using a timestamp, ensures only the latest version can be updated, avoiding data inconsistencies.</SPAN><SPAN><BR /></SPAN></P><P><SPAN>If User 2 refreshes the data, they will be able to see the updated version and then update the data.</SPAN><SPAN> </SPAN></P><P><EM>After refreshing:</EM><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vivek_Sahu_21_8-1736501452012.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210528i3A0FA341CF5C442D/image-size/large?v=v2&px=999" role="button" title="Vivek_Sahu_21_8-1736501452012.png" alt="Vivek_Sahu_21_8-1736501452012.png" /></span></P><P><EM>Now, if User 2 tries to update the data, they can update it:</EM><SPAN> </SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vivek_Sahu_21_9-1736501452013.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210527iF4F2AED1DE03DCAB/image-size/large?v=v2&px=999" role="button" title="Vivek_Sahu_21_9-1736501452013.png" alt="Vivek_Sahu_21_9-1736501452013.png" /></span></P><P><FONT size="5"><STRONG><SPAN>Conclusion:</SPAN></STRONG></FONT><SPAN> </SPAN></P><P><SPAN>ETag in RAP ensures data consistency by using a unique value, like a timestamp, to track changes. It prevents users from accidentally overwriting each other's updates.</SPAN><SPAN> </SPAN></P><P> </P>2025-01-10T14:24:58.475000+01:00https://community.sap.com/t5/application-development-blog-posts/sap-developer-news-january-16th-2025/ba-p/13988216SAP Developer News, January 16th, 20252025-01-16T21:10:00.023000+01:00thomas_junghttps://community.sap.com/t5/user/viewprofilepage/user-id/139<P><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%2FBZdboT6EdZw%3Ffeature%3Doembed&display_name=YouTube&url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DBZdboT6EdZw&image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FBZdboT6EdZw%2Fhqdefault.jpg&type=text%2Fhtml&schema=youtube" width="400" height="225" scrolling="no" title="Uploads from Build Apps, CAP Dec 2024, Joule ABAP Early Adopter, RAP Draft | SAP Developer News" frameborder="0" allow="autoplay; fullscreen; encrypted-media; picture-in-picture;" allowfullscreen="true"></iframe></div></P><P><STRONG>Podcast: </STRONG><A href="https://podcast.opensap.info/sap-developers/2025/01/16/sap-developer-news-january-16th-2025/" target="_blank" rel="nofollow noopener noreferrer">https://podcast.opensap.info/sap-developers/2025/01/16/sap-developer-news-january-16th-2025/</A></P><H3 id="toc-hId-1208595999">DESCRIPTION</H3><P><STRONG>Upload Files from Build Apps to DMS, DOX and Other Services</STRONG></P><UL><LI>Video #1: Set Up SAP Build Apps to Work with DMS – <A href="https://youtu.be/lhBB2mM9Nho" target="_blank" rel="nofollow noopener noreferrer">https://youtu.be/lhBB2mM9Nho</A></LI><LI>Video #2: Call DMS from SAP Build Apps – <A href="https://youtu.be/SJt_BzctwbI" target="_blank" rel="nofollow noopener noreferrer">https://youtu.be/SJt_BzctwbI</A></LI><LI>Video #3: Upload a File from Build Apps to DMS – <A href="https://youtu.be/gIW_tHOaNuY" target="_blank" rel="nofollow noopener noreferrer">https://youtu.be/gIW_tHOaNuY</A></LI><LI>Free DMS projects: <A href="https://github.com/sap-tutorials/sap-build-apps/tree/main/projects/dms" target="_blank" rel="nofollow noopener noreferrer">https://github.com/sap-tutorials/sap-build-apps/tree/main/projects/dms</A></LI><LI>Document Management Service Playlist: <A href="https://www.youtube.com/playlist?list=PL6RpkC85SLQCsKSvIOqMzFKW30B4TKXh-" target="_blank" rel="nofollow noopener noreferrer">https://www.youtube.com/playlist?list=PL6RpkC85SLQCsKSvIOqMzFKW30B4TKXh-</A></LI><LI>Ming Kho’s blog post on Build Apps and DMS: <A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-build-apps-upload-files-to-sap-document-management-service-dms/ba-p/13963628" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/sap-build-apps-upload-files-to-sap-document-management-service-dms/ba-p/13963628</A></LI><LI>Ming Kho’s blog post on Build Apps and DOX: <A href="https://community.sap.com/t5/technology-blogs-by-sap/sap-build-apps-upload-files-to-sap-document-information-extraction-dox/ba-p/13964007" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/sap-build-apps-upload-files-to-sap-document-information-extraction-dox/ba-p/13964007</A></LI></UL><P><STRONG>CAP December 2024 Release</STRONG></P><UL><LI>Release notes <A href="https://cap.cloud.sap/docs/releases/dec24" target="_blank" rel="nofollow noopener noreferrer">https://cap.cloud.sap/docs/releases/dec24</A></LI></UL><P><STRONG>Joule ABAP Developer Capabilities Early Adopter Program</STRONG></P><UL><LI><A href="https://influence.sap.com/sap/ino/#/campaign/3822" target="_blank" rel="noopener noreferrer">https://influence.sap.com/sap/ino/#/campaign/3822</A></LI></UL><P><STRONG>How to implement "readonly : update" for draft instances</STRONG></P><UL><LI><A href="https://community.sap.com/t5/technology-blogs-by-sap/how-to-implement-quot-readonly-update-quot-for-draft-instances/ba-p/13981904" target="_blank">https://community.sap.com/t5/technology-blogs-by-sap/how-to-implement-quot-readonly-update-quot-for-draft-instances/ba-p/13981904</A></LI></UL><P><STRONG>SAP Fiori Innovation Day & UI5 Road Map 2025</STRONG></P><UL><LI>SAP Fiori Innovation Day Silicon Valley: <A href="https://events.sap.com/noam/sap-fiori-innovation-day-silicon-valley/en/home" target="_blank" rel="noopener noreferrer">https://events.sap.com/noam/sap-fiori-innovation-day-silicon-valley/en/home</A></LI><LI>UI5 Road Map Explorer: <A href="https://roadmaps.sap.com/board?PRODUCT=73554900100800001361&range=CURRENT-LAST#Q1%202025" target="_blank" rel="noopener noreferrer">https://roadmaps.sap.com/board?PRODUCT=73554900100800001361&range=CURRENT-LAST#Q1%202025</A></LI></UL><H3 id="toc-hId-1012082494">CHAPTER TITLES</H3><P>0:00 Intro<BR />0:10 Upload Files from Build Apps to DMS, DOX and Other Services<BR />1:51 CAP December 2024 Releas<BR />5:06 Joule ABAP Developer Capabilities Early Adopter Program<BR />6:02 How to implement "readonly : update" for draft instances<BR />6:58 SAP Fiori Innovation Day & UI5 Road Map 2025</P><H3 id="toc-hId-815568989">Transcription</H3><P><STRONG>[Intro]</STRONG> This is the SAP Developer News for January 16th, 2025.</P><P><STRONG>[Daniel]</STRONG> SAP Build Apps has just released a new flow function that lets you upload documents to the BTP Document Management Service, the document information extraction service, or any service that requires a binary upload. Minko, a developer at SAP Build Apps, created the HTTP Destination and request flow function, which takes a multi-part request body and lets you specify a destination, both of which enable you to upload to the services. He has written two blogs, one on using it with DMS and one on using it with DMS, but I want to point out that I've just released three short videos on how to use this flow function with build apps and DMS, and I want to point out that I've just released three short videos on how to use this flow I've released an entire application that lets you navigate through a DMS repo. So it will list all the documents in the root or any folder in the DMS repo, let you upload documents, let you create folders, and let you delete folders and documents. All you need to do is attach your destination to your DMS repo. And I want to point out that we also have a playlist dedicated just to the document management service. It has videos on setting up DMS, unrelated to SAP Build, as well as how to use it with process automation, and build apps. Links to all of that content are in the description.</P><P><STRONG>[DJ]</STRONG> While most of us were taking some time off over the holiday period recently, the CAP team has kept on working and put out another regular monthly release. December 24 of this. As usual, there are plenty of highlights, some of which I want to bring to your attention here. There are so many I've actually got a list and a read through. Got some notes. And this also sees CAP Node.js at 8.6 and CAP Java at 3.6. Okay, so what have we got? There are changes and improvements in the CDS language and compiler area, specifically For example, a completely rewritten CQN specification using TypeScript declaration files, which in turn brings about improved documentation and also some Intellisense operations that are also improved. There's a new beta feature where foreign key elements of managed associations can be explicitly annotated. Moving to the Node.js flavor of CAPs specifically, there are new compiler related life cycle events. They're also in beta. There are some enhancements to CDS Env. These enhancements relate to source formats and profile-specific endv files. And CDSQL has some enhancements. And these enhancements bring about a more robust operation in general and also some new functions for CQN object construction. In the OData arena, there are also some additions and improvements relating to the OData containment feature, and also a move to allow query option-based provision of function parameters, which some of you, I'm sure, will enjoy. In the Java flavor of CAP, there are some important changes in the area of NPM build plugin support, and also the new Calaisi plugin for the document management service is now open source. Last but not least, in the tools area, there are many enhancements to the CDS REPL. Some of you may have seen these enhancements sort of take shape over the course of the first six episodes of the art and science of CAP, a live stream series that we ran recently with the one and only Daniel Hutzl. So I'll put a link to that also in the description to this item, as well as the link to this December 2024. for Capphire release notes, but also for TypeScript developers out there, you can now just use CDS watch to start the server and it will automatically detect a TypeScript project and under the hood it will run CDSTSX for you. There's also more, even more, in this December 2024 release, but I'll leave it to you to go and check out the release notes in Capphire. Until then, see you online.</P><P><STRONG>[Rich]</STRONG> Hey friends, Rich Heilman here. I just wanted to stop in a bit and let you know about the Joule ABAP Developer Capabilities Early Adopter Program for Customers and Partners. That's right, do you want to check out the Bleeding Edge technology helping ABAP developers become more efficient developers? If so, then go to the Influence. site and register for the early adopters program. Registration started on January 15th and will end on February 15th the same day we plan to release to customers. So again, if you are ready to get your hands dirty with AI and using Joule within ADT to help you with ABAP development, then please sign up for this excellent opportunity to try it out, give us some feedback, and make the product better for all. Thanks to ABAP developers, and we'll see you. See you soon. Bye for now.</P><P><STRONG>[Sheena]</STRONG> You might have noticed that when a field is defined as Read Only for updates in a Draft-enabled application, it cannot be edited after an initial value is provided. Andre Fischer in his latest blog post explains how to achieve the editing of such fields in Draft using the dynamic feature control option. For this, just replace the statement read-only update with features instance in your behavior definition. Then in your behavior implementation method, verify whether an active instance of the entity already exists. If yes, the field will be made read only, however, if no active instance exists, the field will remain editable. Please note that this is applicable only when an object is being created as a draft and has not yet been persisted. Check out the details and sample code in the blog post link provided in the description.</P><P><STRONG>[Nico]</STRONG> Hi everyone and welcome to the SAP Developer News. We have some updates in the Fiori and U5 area that we want to put your attention to. First of all, the SAP Fiori Innovation Day happens on February 5th in Silicon Valley. Definitely check it out if you're in the area. AI is going to be a hot topic, there's going to be a partner session, hands -on sessions and an outlook from the Fiori team on what's to come in the future. Check out the link to register in the future. the description of this video. And also related to Fiori, more UI5. The 2025 Roadmap is out now. Go check it out. If you're interested in UI5, there's some interesting items on there, and go follow. All right, check it out. Hope you see you soon. Bye.</P>2025-01-16T21:10:00.023000+01:00https://community.sap.com/t5/technology-blogs-by-members/change-api-state-of-your-abap-cloud-development-objects-in-bulk-mode/ba-p/13988272Change API State of your ABAP Cloud Development Objects in Bulk Mode2025-01-17T15:45:04.919000+01:00satish_inamdarhttps://community.sap.com/t5/user/viewprofilepage/user-id/150021<P><SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="API_State.jpg" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/213159i5BF6C79CB0BF82AF/image-size/large?v=v2&px=999" role="button" title="API_State.jpg" alt="API_State.jpg" /></span></SPAN></P><P><SPAN>When developing software components, it's often beneficial to reuse existing development objects in other parts of your project or in entirely different projects. To enable this reusability, you need to release these objects with "visibility use" in Cloud Development.</SPAN></P><P><SPAN>While you can achieve this manually through your Eclipse IDE, the process can be quite time-consuming, especially when dealing with a large number of objects. Each object needs to be individually released, which can quickly become a tedious and inefficient task.</SPAN></P><P><SPAN>To streamline this process and increase productivity, we can leverage the power of the XCO library. This library provides tools and functionalities that allow you to release objects programmatically, saving you valuable time and effort. </SPAN></P><P><SPAN>In this blog post, we will look at a sample working code that can help you release:</SPAN></P><UL><LI><SPAN>Domains</SPAN></LI><LI><SPAN>Data Elements</SPAN></LI><LI><SPAN>Tables</SPAN></LI><LI><SPAN>Classes</SPAN></LI></UL><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>"----------------------------------------------------------------------------
" Purpose: This program sets API State to Released
" Note: Developer should first set the TR Number Correctly
" Currently Supported For:
" 1. Domains
" 2. Data Elements
" 3. DDIC Tables
" 4. Classes
" Also supports display only mode, which only shows the current state (RELEASED or NOT RELEASED)
"----------------------------------------------------------------------------
CLASS zcl_set_api_state DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
PRIVATE SECTION.
TYPES: BEGIN OF details_struc,
name TYPE string,
api_state TYPE string,
END OF details_struc.
CLASS-DATA details_tab TYPE TABLE OF details_struc WITH EMPTY KEY.
TYPES: BEGIN OF obj_type_switch,
doma TYPE abap_boolean,
dtel TYPE abap_boolean,
tabl TYPE abap_boolean,
clas TYPE abap_boolean,
END OF obj_type_switch.
CLASS-DATA selection_switch TYPE obj_type_switch.
ENDCLASS.
CLASS zcl_set_api_state IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA package TYPE sxco_package.
DATA tr TYPE sxco_transport
DATA display_only TYPE abap_boolean.
" TODO: Set value for package and transport request
"package = <Provide the package name of objects>
"tr = <Provide the TR number>
DATA(lo_transport) = xco_cp_cts=>transport->for( tr ).
" TODO: If you only want to only display set to TRUE, if you want to release set this to FALSE
display_only = abap_true.
" TODO: What type of objects you want to select?
" If you want to select all, set all elements of the structure selection_switch to TRUE
" Else selectively pick and choose
selection_switch-clas = abap_true.
selection_switch-doma = abap_false.
selection_switch-dtel = abap_false.
selection_switch-tabl = abap_false.
DATA(package_handle) = xco_cp_abap_repository=>package->for( package ).
DATA(lo_api_state_rel) = xco_cp_ars=>api_state->released( VALUE #( ( xco_cp_ars=>visibility->sap_cloud_platform ) ) ).
IF selection_switch-doma = abap_false AND selection_switch-dtel = abap_false
AND selection_switch-tabl = abap_false AND selection_switch-clas = abap_false.
out->write( 'No object types selected' ).
RETURN.
ENDIF.
IF selection_switch-doma = abap_true.
" Getting all domains contained in the package
DATA(all_domains) = xco_cp_abap_repository=>objects->doma->all->in( package_handle )->get( ).
LOOP AT all_domains ASSIGNING FIELD-SYMBOL(<fs_doma>).
APPEND VALUE #( name = <fs_doma>->name
api_state = <fs_doma>->get_api_state( )->get_release_state( )->value )
TO details_tab.
ENDLOOP.
SORT details_tab BY name.
out->write( |\nThe package { package } includes the following { lines( details_tab ) } domains:| ).
out->write( details_tab ).
IF display_only <> abap_true.
" Releasing ....
out->write( 'Releasing ....' ).
LOOP AT all_domains ASSIGNING FIELD-SYMBOL(<fs_doma1>).
IF <fs_doma1>->get_api_state( )->get_release_state( )->value = 'RELEASED'.
out->write( |\nThe Domain: { <fs_doma1>->name } Already released| ).
CONTINUE.
ENDIF.
TRY.
DATA(lo_doma) = xco_cp_abap_repository=>object->doma->for( <fs_doma1>->name ).
lo_doma->set_api_state( io_change_scenario = lo_transport
io_api_state = lo_api_state_rel ).
CATCH cx_root INTO DATA(lo_exp).
out->write( 'Error occurred during releasing of API State' ).
out->write( lo_exp->get_text( ) ).
RETURN.
ENDTRY.
ENDLOOP.
out->write( 'API State of Domains Set to Released ...' ).
ENDIF.
ENDIF.
IF selection_switch-dtel = abap_true.
" Getting all data elements contained in the package
DATA(all_dtel) = xco_cp_abap_repository=>objects->dtel->all->in( package_handle )->get( ).
CLEAR details_tab.
LOOP AT all_dtel ASSIGNING FIELD-SYMBOL(<fs_dtel>).
APPEND VALUE #( name = <fs_dtel>->name
api_state = <fs_dtel>->get_api_state( )->get_release_state( )->value )
TO details_tab.
ENDLOOP.
SORT details_tab BY name.
out->write( |\nThe package { package } includes the following { lines( details_tab ) } data elements:| ).
out->write( details_tab ).
IF display_only <> abap_true.
" Releasing ....
out->write( 'Releasing ....' ).
LOOP AT all_dtel ASSIGNING FIELD-SYMBOL(<fs_dtel1>).
IF <fs_dtel1>->get_api_state( )->get_release_state( )->value = 'RELEASED'.
out->write( |\nThe Data element: { <fs_dtel1>->name } Already released| ).
CONTINUE.
ENDIF.
TRY.
DATA(lo_dtel) = xco_cp_abap_repository=>object->dtel->for( <fs_dtel1>->name ).
lo_dtel->set_api_state( io_change_scenario = lo_transport
io_api_state = lo_api_state_rel ).
CATCH cx_root INTO lo_exp.
out->write( 'Error occurred during releasing of API State' ).
out->write( lo_exp->get_text( ) ).
RETURN.
ENDTRY.
ENDLOOP.
out->write( 'API State of Data Elements Set to Released ...' ).
ENDIF.
ENDIF.
IF selection_switch-tabl = abap_true.
" Getting all database tables contained in the package
DATA(all_tabl) = xco_cp_abap_repository=>objects->tabl->all->in( package_handle )->get( ).
CLEAR details_tab.
LOOP AT all_tabl ASSIGNING FIELD-SYMBOL(<fs_tabl>).
DATA(db_table) = CONV sxco_dbt_object_name( <fs_tabl>->name ).
DATA(db_handler) = xco_cp_abap_dictionary=>database_table( db_table ).
DATA(db_exists) = db_handler->exists( ).
IF db_exists IS NOT INITIAL.
DATA(db_rel_state) = db_handler->get_api_state( )->get_release_state( )->value.
ELSE.
db_rel_state = 'Could not be determined'.
ENDIF.
APPEND VALUE #( name = <fs_tabl>->name
api_state = db_rel_state )
TO details_tab.
ENDLOOP.
SORT details_tab BY name.
out->write( |\nThe package { package } includes the following { lines( details_tab ) } Tables:| ).
out->write( details_tab ).
IF display_only <> abap_true.
" Releasing ....
out->write( 'Releasing ....' ).
LOOP AT all_tabl ASSIGNING FIELD-SYMBOL(<fs_tabl1>).
TRY.
db_table = CONV sxco_dbt_object_name( <fs_tabl1>->name ).
db_handler = xco_cp_abap_dictionary=>database_table( db_table ).
db_exists = db_handler->exists( ).
IF db_exists IS NOT INITIAL.
db_handler->set_api_state( io_api_state = lo_api_state_rel
io_change_scenario = lo_transport ).
ELSE.
out->write( |\nHandler doesn't exist for DB Table: { <fs_tabl1>->name }| ).
ENDIF.
CATCH cx_root INTO lo_exp.
out->write( 'Error occurred during releasing of API State' ).
out->write( lo_exp->get_text( ) ).
RETURN.
ENDTRY.
ENDLOOP.
out->write( 'API State of Database tables Set to Released ...' ).
ENDIF.
ENDIF.
IF selection_switch-clas = abap_true.
" Getting all repository objects contained in the package
DATA(all_clas) = xco_cp_abap_repository=>objects->clas->all->in( package_handle )->get( ).
CLEAR details_tab.
LOOP AT all_clas ASSIGNING FIELD-SYMBOL(<fs_clas>).
APPEND VALUE #( name = <fs_clas>->name
api_state = <fs_clas>->get_api_state( )->get_release_state( )->value )
TO details_tab.
ENDLOOP.
SORT details_tab BY name.
out->write( |\nThe package { package } includes the following { lines( details_tab ) } classes:| ).
out->write( details_tab ).
IF display_only <> abap_true.
" Releasing ....
out->write( 'Releasing ....' ).
LOOP AT all_clas ASSIGNING FIELD-SYMBOL(<fs_clas1>).
IF <fs_clas1>->get_api_state( )->get_release_state( )->value = 'RELEASED'.
out->write( |\nThe Class: { <fs_clas1>->name } Already released| ).
CONTINUE.
ENDIF.
TRY.
DATA(lo_clas) = xco_cp_abap_repository=>object->clas->for( <fs_clas1>->name ).
lo_clas->set_api_state( io_change_scenario = lo_transport
io_api_state = lo_api_state_rel ).
CATCH cx_root INTO lo_exp.
out->write( |Error occurred during releasing of API State, Class Name: { <fs_clas1>->name }| ).
out->write( lo_exp->get_text( ) ).
CONTINUE.
ENDTRY.
ENDLOOP.
out->write( 'API State of Classes Set to Released ...' ).
ENDIF.
ENDIF.
ENDMETHOD.
ENDCLASS.</code></pre><P> </P><P>The program needs a few variables to be set, which are indicated by TODO comments placed in the beginning of the program. If the <FONT color="#993366"><STRONG><FONT face="andale mono,times">display_only</FONT></STRONG></FONT> flag is set to true then only the current API state of the object is displayed. You can also control for which types of object you want to set the API State, by using the <FONT face="andale mono,times"><STRONG><FONT color="#993366">selection_switch</FONT></STRONG> </FONT>variable. </P><P>Currently the program is designed to select all the Classes/Domains/Data Elements/Tables of a package. However you can easily introduce filters to restrict this.</P><P>A sample output is shown below:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-left" image-alt="API_Setter_Op.jpg" style="width: 524px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/213168iD965F46D8911C9F6/image-size/large?v=v2&px=999" role="button" title="API_Setter_Op.jpg" alt="API_Setter_Op.jpg" /></span></P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P> </P><P><FONT color="#339966"><EM><FONT size="5">Hope this makes the job of ABAP Cloud Developers a bit more easy !!</FONT></EM></FONT></P><P><FONT size="3"><EM>If you have other ideas on how we can efficiently manage this task do share in the comments!</EM></FONT></P><P> </P>2025-01-17T15:45:04.919000+01:00https://community.sap.com/t5/technology-blogs-by-members/enable-odata-streams-in-rap/ba-p/13990426Enable OData Streams in RAP2025-01-20T06:28:13.387000+01:00pavankumar_reddy90https://community.sap.com/t5/user/viewprofilepage/user-id/189954<P><SPAN><STRONG>Problem statement:</STRONG><BR />How to enable OData Streams such as excel, pdf, Images and other large objects using standard RAP Based application development without using UI5 tooling?</SPAN></P><P><STRONG>Solution:</STRONG></P><P><SPAN>With the latest SAP BTP ABAP Environment 2208 release the RAP framework now supports OData streams. It is now possible to enable your RAP application to maintain and handle Large Objects(LOBs).This feature provides end users an option to upload external files of different file formats such as PDF, XLSX , binary file format and other types hence allowing media handling.<BR /><BR />I am on of the presenter for this topic at ABAP Conference and int the below youtube recording. This topic covers content related to how to enable large objects using RAP (ABAP RESTful Programming Model ). Upload functionality using custom actions, download functionality using custom actions, how to use XCO library to read and write XLSX content and some useful links which can be explored about OData Streams in RAP.</SPAN></P><P><BR />ABAP Conference recording: <A href="https://www.youtube.com/watch?v=QyPEzRHA9Lo&ab_channel=ABAPConf" target="_blank" rel="noopener nofollow noreferrer">Enable OData Streams in RAP</A></P><P>Slides: <A href="https://abapconf.org/abapconf2024/#/agenda" target="_blank" rel="noopener nofollow noreferrer">https://abapconf.org/abapconf2024/#/agenda</A></P><P>Check for topic "<A class="" href="https://abapconf.org/abapconf2024/#" target="_blank" rel="noopener nofollow noreferrer">Enable OData Streams in RAP</A>" where you can find the link to download slides in pdf document.<BR /><BR />Use cases covered:</P><OL><LI><STRONG>Working with Large Objects</STRONG></LI><LI><STRONG>Upload Functionality using Custom Action</STRONG></LI><LI><STRONG>Download Functionality using Custom Action</STRONG></LI><LI><STRONG>Use XCO library to read and write XLSX Content</STRONG></LI></OL><P><STRONG>Code based GitHub URL's:</STRONG></P><P>1. Upload and Download Functionality application : <A href="https://github.com/rvrrpk/OdataStreamsRAP" target="_blank" rel="noopener nofollow noreferrer">https://github.com/rvrrpk/OdataStreamsRAP</A></P><P>2. Download History Application : <A href="https://github.com/rvrrpk/DownloadHistory" target="_blank" rel="noopener nofollow noreferrer">https://github.com/rvrrpk/DownloadHistory</A></P><P> </P><P> </P><P> </P><P> </P>2025-01-20T06:28:13.387000+01:00https://community.sap.com/t5/technology-blogs-by-sap/unlock-your-future-prove-your-abap-cloud-readiness-today/ba-p/13990888Unlock Your Future: Prove Your ABAP Cloud Readiness Today!2025-01-20T13:34:03.019000+01:00Johannhttps://community.sap.com/t5/user/viewprofilepage/user-id/137238<P>In the fast-evolving tech landscape, staying ahead means embracing the future. And in the world of ABAP development, that future is ABAP Cloud.</P><P><STRONG>What is ABAP Cloud?</STRONG></P><P>ABAP Cloud is the cutting-edge evolution in ABAP development. It's your gateway to creating cloud-ready business applications, services, and extensions that stand the test of time. Imagine harnessing the power of Core Data Services (CDS) for seamless data modelling, the ABAP RESTful Application Programming Model (RAP) for streamlined service development, and a cloud-optimized ABAP language that makes your business logic soar.</P><P>This all-encompassing programming model caters to both the SAP Business Technology Platform and SAP S/4HANA, working harmoniously across public cloud, private cloud, and on-premise environments. It's not just the next step—it's the future.</P><P><STRONG>Get Certified and Stand Out</STRONG></P><P>Ready to showcase your ABAP Cloud expertise? The <A href="https://learning.sap.com/certifications/sap-certified-associate-back-end-developer-abap-cloud" target="_blank" rel="noopener noreferrer">SAP Certified Associate - Back-End Developer - ABAP Cloud</A> certification is your ticket to proving your prowess. But how do you prepare for this transformative exam?</P><P><STRONG>Explore Your Training Options</STRONG></P><P>Whether you're a fan of interactive classroom experiences or prefer the flexibility of e-learning, SAP has you covered.</P><P>If you appreciate the benefits of classroom training, you can prepare for the certification with the classroom training courses <A href="https://training.sap.com/course/s4d400" target="_blank" rel="noopener noreferrer">S4D400 (Basic ABAP Programming)</A>, <A href="https://training.sap.com/course/s4d401" target="_blank" rel="noopener noreferrer">S4D401 (Intermediate ABAP Programming)</A> and <A href="https://training.sap.com/course/s4d430" target="_blank" rel="noopener noreferrer">S4D430 (Data Modelling in ABAP Dictionary and ABAP Core Data Services)</A> - as shown in the curriculum map below. Building on <A href="https://training.sap.com/course/s4d430" target="_blank" rel="noopener noreferrer">S4D430</A>, the free e-learning <A href="https://learning.sap.com/learning-journeys/practicing-clean-core-extensibility-for-sap-s-4hana-cloud" target="_blank" rel="noopener noreferrer">Practicing Clean Core Extensibility for SAP S/4HANA Cloud</A> covers the remaining content required for the exam.</P><P><STRONG> </STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Johann_0-1737376246920.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/214402i099854EFF44F3D4E/image-size/medium?v=v2&px=400" role="button" title="Johann_0-1737376246920.png" alt="Johann_0-1737376246920.png" /></span></P><P> </P><P><BR /> </P><P><STRONG>In-Depth Knowledge:</STRONG> Even though the 5-day classroom training course <A href="https://training.sap.com/course/s4d437" target="_blank" rel="noopener noreferrer">S4D437 (Building Transactional Apps with the ABAP RESTful Application Programming Model)</A> - also shown in the curriculum map - isn't included in the exam, it's a goldmine for those serious about mastering the ABAP RESTful Application Programming Model. We highly recommend it!</P><P><STRONG>E-Learning Flexibility: </STRONG><STRONG>For those who prefer learning at their own pace, there are excellent alternatives. </STRONG>Instead of attending the classroom training courses <A href="https://training.sap.com/course/s4d400" target="_blank" rel="noopener noreferrer">S4D400</A>, <A href="https://training.sap.com/course/s4d401" target="_blank" rel="noopener noreferrer">S4D401</A> and <A href="https://training.sap.com/course/s4d430" target="_blank" rel="noopener noreferrer">S4D430</A>, you can alternatively work through the free e-learning <A href="https://learning.sap.com/learning-journeys/acquire-core-abap-skills" target="_blank" rel="noopener noreferrer">Acquiring Core ABAP Skills</A>. It covers the entirety of the three classroom training courses, allowing you to study whenever and wherever you want.<BR /><BR /><STRONG>Mix and Match Your Learning Path</STRONG></P><P>Flexibility is key. Combine classroom and e-learning approaches to fit your schedule and learning style. For example, attend <A href="https://training.sap.com/course/s4d400" target="_blank" rel="noopener noreferrer">S4D400</A> in person, then switch to the e-learning <A href="https://learning.sap.com/learning-journeys/acquire-core-abap-skills" target="_blank" rel="noopener noreferrer">Acquiring Core ABAP Skills</A> to cover the content of <A href="https://training.sap.com/course/s4d401" target="_blank" rel="noopener noreferrer">S4D401</A> and <A href="https://training.sap.com/course/s4d430" target="_blank" rel="noopener noreferrer">S4D430</A> — it's entirely your call. The e-learning content is carefully designed to mirror classroom training, so you won't miss a beat.</P><P><STRONG>Your Path, Your Future</STRONG></P><P>Chart your own course to ABAP Cloud certification. Take control of your learning journey, prove your skills, and unlock unparalleled opportunities in the tech world.</P><P>Ready to embark on this exciting journey? Your future in ABAP Cloud awaits!</P><P>This article has been created by Christoph Knecht</P>2025-01-20T13:34:03.019000+01:00https://community.sap.com/t5/technology-blogs-by-sap/customer-amp-partner-roundtable-for-sap-btp-abap-environment-20/ba-p/13995613Customer & Partner Roundtable for SAP BTP ABAP Environment #202025-01-24T11:01:14.541000+01:00iwona_hahnhttps://community.sap.com/t5/user/viewprofilepage/user-id/4326<H3 id="toc-hId-1209433988"><STRONG><SPAN class="lia-unicode-emoji"><span class="lia-unicode-emoji" title=":backhand_index_pointing_right:">👉</span></SPAN> The call for contributions for one of the upcoming roundtables is open! </STRONG></H3><P> </P><DIV><TABLE><TBODY><TR><TD>If you want to show a demo or share a use case scenario for SAP BTP ABAP Environment send us an<SPAN> </SPAN><A href="mailto:sap_btp_abap_environment@sap.com" target="_blank" rel="noopener nofollow noreferrer">email</A> and we will get back to you.</TD></TR></TBODY></TABLE><SPAN> </SPAN></DIV><H2 id="toc-hId-883837764">Introduction</H2><P> </P><DIV><SPAN class="">A</SPAN><SPAN class="">s<SPAN> </SPAN></SPAN><A href="https://www.sap.com/products/technology-platform/abap/environment.html" target="_blank" rel="noopener noreferrer"><SPAN class="">SAP BTP ABAP environment (aka Steampunk)</SPAN><SPAN> </SPAN></A>and ABAP Cloud<SPAN> </SPAN><SPAN class="">became </SPAN><SPAN class="">more popular</SPAN><SPAN class=""><SPAN> </SPAN>inside and outside of SAP, there is a high demand for rolling out the latest product news and updates, asking questions, and showing demos. </SPAN><BR /><BR /><SPAN class="lia-unicode-emoji"><span class="lia-unicode-emoji" title=":light_bulb:">💡</span></SPAN> You can find the slides presented, recordings, and further references from the previous roundtables in this<SPAN> </SPAN><A href="https://github.com/iwonahahn/SAP-BTP-ABAP-Environment-Roundtable/tree/main" target="_blank" rel="noopener nofollow noreferrer">GitHub repository</A>.<BR /><BR /></DIV><DIV><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="iwona_hahn_1-1711369871866.jpeg" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/85948i899EEF37EF74A54C/image-size/medium?v=v2&px=400" role="button" title="iwona_hahn_1-1711369871866.jpeg" alt="iwona_hahn_1-1711369871866.jpeg" /></span><H2 id="toc-hId-687324259"><BR />Meeting Information<BR /><BR /></H2><STRONG>When: </STRONG><BR /><UL><LI><STRONG><SPAN class="">February 13th</SPAN></STRONG>, 10:00 - 11:00 AM CET –<SPAN> </SPAN><A href="https://sap-se.zoom.us/meeting/register/8NnwESGdS9K3oYXDMoAQ_A" target="_blank" rel="nofollow noopener noreferrer">Zoom Meeting</A> (<STRONG>please register</STRONG><SPAN> </SPAN>in advance) </LI></UL></DIV><DIV> </DIV><DIV><STRONG>Who:</STRONG><UL><LI>All interested <STRONG>customers, partners,</STRONG> and <STRONG>stakeholders</STRONG> are invited to join this roundtable</LI><LI><STRONG>BTP ABAP team</STRONG>:<UL class="lia-list-style-type-circle"><LI><A href="https://community.sap.com/t5/user/viewprofilepage/user-id/4296" target="_blank">Frank Jentsch</A> <SPAN class="">(Product Lead for SAP BTP ABAP Environment)</SPAN></LI><LI><A href="https://community.sap.com/t5/user/viewprofilepage/user-id/441355" target="_blank">Uenal Akkaya</A> & <A href="https://community.sap.com/t5/user/viewprofilepage/user-id/185696" target="_blank">Thomas Alexander Ritter</A><SPAN> (</SPAN><SPAN class="">ABAP Cloud Dev Tools)</SPAN></LI><LI><A href="https://community.sap.com/t5/user/viewprofilepage/user-id/4326" target="_self"><SPAN class="">Iwona Hahn</SPAN></A>, <A href="https://community.sap.com/t5/user/viewprofilepage/user-id/151005" target="_self">Burcu Karlidag</A><SPAN class="">, <A href="https://community.sap.com/t5/user/viewprofilepage/user-id/1612023" target="_blank">Ronny Pahlke</A>, <A href="https://community.sap.com/t5/user/viewprofilepage/user-id/1641196" target="_blank">Nora Klemp</A></SPAN><SPAN class=""> (BTP ABAP Product Management)</SPAN></LI></UL></LI></UL></DIV><DIV><STRONG>Preliminary Agenda:</STRONG><BR /><UL><LI>Product update for SAP BTP ABAP Environment</LI><LI><SPAN>ABAP IDE Actions including live demo</SPAN></LI><LI>Q&A </LI></UL><SPAN>Looking forward to meeting you!</SPAN></DIV><DIV> </DIV><DIV><A href="https://sap-se.zoom.us/meeting/register/8NnwESGdS9K3oYXDMoAQ_A" target="_blank" rel="noopener nofollow noreferrer"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="iwona_hahn_2-1711369871851.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/85947i01677A9AE51AAC1D/image-size/medium?v=v2&px=400" role="button" title="iwona_hahn_2-1711369871851.png" alt="iwona_hahn_2-1711369871851.png" /></span></A><BR /><BR /><SPAN>Check out our</SPAN><SPAN> </SPAN><A href="https://pages.community.sap.com/topics/btp-abap-environment" target="_blank" rel="noopener noreferrer">SAP Business Technology ABAP Environment</A><SPAN> page in SAP Community </SPAN><SPAN>for </SPAN><SPAN>product </SPAN><SPAN>updates </SPAN><SPAN>and </SPAN><SPAN>upcoming events.</SPAN></DIV>2025-01-24T11:01:14.541000+01:00https://community.sap.com/t5/technology-blogs-by-members/custom-value-help-creation-for-a-particular-field-in-sap-rap/ba-p/13992340Custom Value Help Creation For a Particular Field In SAP RAP.2025-01-24T16:38:12.930000+01:00Basant_Joshihttps://community.sap.com/t5/user/viewprofilepage/user-id/1429885<P><FONT size="5"><U><STRONG>Introduction </STRONG></U></FONT></P><P><STRONG> </STRONG>In SAP RAP (Restful ABAP Programming), a <STRONG>custom entity</STRONG> refers to a user-defined data model that represents business data specific to your needs. It’s typically created using Core Data Services (CDS) views and exposed as an OData service for consumption in applications like Fiori.</P><P>Custom entities in RAP empower developers to create tailored data models that fit unique business scenarios while easily integrating with SAP's cloud and UI platforms.</P><P>The custom entity provides a structure and implements the logic via an ABAP class. The entity itself does not contain any data but must always be called by the SADL framework first. This is why custom entities are mainly used in RAP applications.</P><P><STRONG>In this blog we will make Value help for Status field In our RAP Project.</STRONG></P><P><U><STRONG>Final Output :-</STRONG></U></P><P> </P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Basant_Joshi_0-1737442448472.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/214687iA886C54082A8F33C/image-size/medium?v=v2&px=400" role="button" title="Basant_Joshi_0-1737442448472.png" alt="Basant_Joshi_0-1737442448472.png" /></span></P><P> </P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Basant_Joshi_1-1737442448477.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/214688iA0F24E63F4531352/image-size/large?v=v2&px=999" role="button" title="Basant_Joshi_1-1737442448477.png" alt="Basant_Joshi_1-1737442448477.png" /></span></P><P><FONT size="5"><U><STRONG>Implementation</STRONG></U></FONT></P><P>In the first step, we begin by creating the Core Data Service and the ABAP class.</P><P><FONT size="4"><STRONG>1. Class</STRONG></FONT></P><P>Since the class in the annotation is also checked when the custom entity is created, we implement the empty class first.</P><P>To do this, we create the class and use the interface <STRONG>IF_RAP_QUERY_PROVIDER,</STRONG> which expects the custom entity.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Basant_Joshi_2-1737442847590.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/214698i3024A47278C38DCB/image-size/medium?v=v2&px=400" role="button" title="Basant_Joshi_2-1737442847590.png" alt="Basant_Joshi_2-1737442847590.png" /></span></P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>CLASS zcl_status_query DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_rap_query_provider .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_status_query IMPLEMENTATION.
METHOD if_rap_query_provider~select.
* write logic here
ENDMETHOD.
ENDCLASS.</code></pre><P> </P><P><STRONG>2. </STRONG><FONT size="4"><STRONG>Core Data Service</STRONG></FONT></P><P>In the next step, we create the Core Data Service using the context menu. We use the CDS template <STRONG>"defineCustomEntityWithParameters"</STRONG> as a template:-</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2025-01-21 103101.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/214768iE6D7AF403CDF4EBD/image-size/medium?v=v2&px=400" role="button" title="Screenshot 2025-01-21 103101.png" alt="Screenshot 2025-01-21 103101.png" /></span></P><P> </P><P> </P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Basant_Joshi_7-1737444804329.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/214728i18BDA767731AF7A7/image-size/medium?v=v2&px=400" role="button" title="Basant_Joshi_7-1737444804329.png" alt="Basant_Joshi_7-1737444804329.png" /></span></P><P> Now Add This annotation at CDS</P><P> </P><pre class="lia-code-sample language-abap"><code>@ObjectModel.query.implementedBy: 'ABAP:ZCL_STATUS_QUERY'</code></pre><P> </P><P>Now We will create two fields:</P><UL><LI>First we create a status field with appropriate data type. In this we will enter the description of the status field.</LI><LI> The next field is the short description of the status. ( ex: <STRONG>N = New</STRONG> ).</LI></UL><P>Since we are using built-in data types, we also set the label and tooltip for the user so that the texts appear in the UI.</P><P> </P><pre class="lia-code-sample language-abap"><code>@EndUserText.label: 'Value Help cds for status data element'
@ObjectModel.query.implementedBy: 'ABAP:ZCL_STATUS_QUERY'
define custom entity ZCDi_status_VH
{
@EndUserText.label: 'Status'
@EndUserText.quickInfo: 'Currently available status'
key status : abap.char(10);
@EndUserText.label: 'Status(Short)'
@EndUserText.quickInfo: 'Short Name for the status'
Status_short : abap.char(1);
}</code></pre><P> </P><P>We have now created the basic elements that we need for the search help. In this section we implement the necessary logic to see data in the UI.</P><P> To do this, we bind the search help to the field in the projection view.</P><P> </P><pre class="lia-code-sample language-abap"><code> @Consumption.valueHelpDefinition: [{ entity: { name: 'ZCDI_STATUS_VH', element: 'status' } }]
Status,</code></pre><P> </P><P>Since value help must also be released externally, you should include the view in your service definition.</P><P>(<STRONG>NOTE:</STRONG> Expose only if you did association with the custom CDS. In this case we will do ) .</P><P> </P><pre class="lia-code-sample language-abap"><code>@EndUserText.label: 'Employee table service defination'
define service Zsd_empheader {
expose zcdp_Empheader;
expose zcdp_address;
expose zcdp_items;
expose ZCDi_status_VH;
}</code></pre><P> </P><P><FONT size="4"><STRONG>3. Extending the previously defined class</STRONG></FONT></P><P>Let's now extend the query class with the logic we need to be able to use the value help easily. To do this, we need an internal table with the data type of the custom entity. We fill this with the appropriate data</P><P> </P><pre class="lia-code-sample language-abap"><code> DATA: lt_create TYPE STANDARD TABLE OF zcdi_status_vh WITH EMPTY KEY.
lt_create = VALUE #( ( status = 'New' Status_short = 'N' )
( status = 'Completed' Status_short = 'C' )
( status = 'Invalid' Status_short = 'I' )
( status = 'Pending' Status_short = 'P' )
).
IF io_request->is_data_requested( ).
io_response->set_data( lt_create ).
ENDIF.
IF io_request->is_total_numb_of_rec_requested( ).
io_response->set_total_number_of_records( lines( lt_create ) ).
ENDIF.
io_request->get_sort_elements( ).
io_request->get_paging( ).</code></pre><P> </P><P>To return the data, we still have to call the appropriate REPSONSE methods. Here it is important to only call the methods if the framework requests it, otherwise an error will occur. Therefore, we first ask whether the fields have been requested and then call the method. It is also important that the two methods must always be implemented and should not, for example, be in a TRY/CATCH, where they may not be called if an error occurs.</P><P> </P><pre class="lia-code-sample language-abap"><code> IF io_request->is_data_requested( ).
io_response->set_data( lt_create ).
ENDIF.
IF io_request->is_total_numb_of_rec_requested( ).
io_response->set_total_number_of_records( lines( lt_create ) ).
ENDIF.</code></pre><P> </P><P>In addition to this method, we also must call the GET_PAGING method, for which we receive a similar error. The call to the methods must be implemented within the method call.</P><P> </P><pre class="lia-code-sample language-abap"><code> io_request->get_sort_elements( ).
io_request->get_paging( ).</code></pre><P> </P><P>Now we have to associate our custom CDS with the root CDS where status field is present and expose the custom status entity.</P><P> </P><pre class="lia-code-sample language-abap"><code>association to ZCDi_status_VH as _status on $projection.Status = _status.status.
*expose it
_status,</code></pre><P> </P><UL><LI><STRONG>status -> Field in the custom entity.</STRONG></LI><LI><STRONG>Status -> field in the root CDS.</STRONG></LI><LI><STRONG> </STRONG><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Screenshot 2025-01-21 121004.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/214713iE74F4E85DC81D942/image-size/large?v=v2&px=999" role="button" title="Screenshot 2025-01-21 121004.png" alt="Screenshot 2025-01-21 121004.png" /></span></LI></UL><P><STRONG>Result :-</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Basant_Joshi_3-1737443983159.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/214714i9017A218AEE72EA4/image-size/medium?v=v2&px=400" role="button" title="Basant_Joshi_3-1737443983159.png" alt="Basant_Joshi_3-1737443983159.png" /></span></P><P> </P><P><STRONG>On Clicking value help , value help window will appear.</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Basant_Joshi_4-1737443983162.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/214716i0E9F8652DBE29B11/image-size/large?v=v2&px=999" role="button" title="Basant_Joshi_4-1737443983162.png" alt="Basant_Joshi_4-1737443983162.png" /></span></P><P> </P><P><STRONG>On clicking to the required status, it will populate In the field.</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Basant_Joshi_5-1737443983164.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/214715i9474B57BC789740A/image-size/large?v=v2&px=999" role="button" title="Basant_Joshi_5-1737443983164.png" alt="Basant_Joshi_5-1737443983164.png" /></span></P><P> </P><P> </P>2025-01-24T16:38:12.930000+01:00https://community.sap.com/t5/technology-blogs-by-members/create-deep-entity-using-rap-unmanaged/ba-p/13993060CREATE_DEEP_ENTITY using RAP ( Unmanaged )2025-01-24T16:44:09.141000+01:00Mahmoud_Waelhttps://community.sap.com/t5/user/viewprofilepage/user-id/178735<P>Hello Experts,</P><P><SPAN>In this blog, We will learn how to create a simple RAP OData API and use it to achieve a Deep entity set creation operation which is requested in lot of projects and Custom services especially in complex integration scenarios .</SPAN></P><P><SPAN>In this example, we will be using a custom cds view entities based on standard tables for header and items, unmanaged behavior definition, service definition and binding . </SPAN></P><P>Step 1 : Parent CDS :</P><P> </P><pre class="lia-code-sample language-javascript"><code>@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Production order Cds view'
@Metadata.ignorePropagatedAnnotations: true
define root view entity z7pi_production_order
as select from aufk as _order
composition [1..*] of z7pi_serial_number as _serial
{
key aufnr as Production_order,
auart,
_serial
}</code></pre><P> </P><P> </P><P>Step 2 : Child CDS :</P><P> </P><pre class="lia-code-sample language-javascript"><code>@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'serial Number Cds view'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType:{
serviceQuality: #X,
sizeCategory: #S,
dataClass: #MIXED
}
define view entity z7pi_serial_number
as select from objk
association [0..1] to ser05 on objk.obknr = ser05.obknr
association [0..1] to ser06 on objk.obknr = ser06.obknr
association to parent z7pi_production_order as _order
on $projection.Production_order = _order.Production_order
{
key ser05.ppaufart as Production_order,
key objk.sernr as serial,
key ser06.exidv as hu,
_order
}</code></pre><P> </P><P> </P><P>Step 3 : Unmanaged Behavior Definition :</P><P> </P><pre class="lia-code-sample language-abap"><code>unmanaged implementation in class z7pbp_7pi_production_order unique;
strict ( 2 );
define behavior for z7pi_production_order alias _order
//late numbering
lock master
authorization master ( instance )
//etag master <field_name>
{
field ( features : instance ) auart ;
create;
update;
delete;
association _serial { create; }
}
define behavior for z7pi_serial_number alias _serial
//late numbering
lock dependent by _order
authorization dependent by _order
//etag master <field_name>
{
update;
delete;
field ( readonly ) Production_order;
association _order;
}</code></pre><P> </P><P> </P><P>Step 4 : using quick fix create the implementation Class</P><P>Step 5 : comment or remove the <SPAN>create and cba_association create methods</SPAN></P><P><SPAN>we remove both methods and create a new method using the events from the removed ones</SPAN></P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>CLASS lhc__order DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
IMPORTING keys REQUEST requested_authorizations FOR _order RESULT result.
* METHODS create FOR MODIFY
* IMPORTING entities FOR CREATE _order.
METHODS deep_create FOR MODIFY
IMPORTING
order FOR CREATE _order
serial FOR CREATE _order\_serial.
METHODS update FOR MODIFY
IMPORTING entities FOR UPDATE _order.
METHODS delete FOR MODIFY
IMPORTING keys FOR DELETE _order.
METHODS read FOR READ
IMPORTING keys FOR READ _order RESULT result.
METHODS lock FOR LOCK
IMPORTING keys FOR LOCK _order.
METHODS rba_serial FOR READ
IMPORTING keys_rba FOR READ _order\_serial FULL result_requested RESULT result LINK association_links.
METHODS get_instance_features FOR INSTANCE FEATURES
IMPORTING keys REQUEST requested_features FOR _order RESULT result.
* METHODS cba_serial FOR MODIFY
* IMPORTING entities_cba FOR CREATE _order\_serial.
ENDCLASS.</code></pre><P> </P><P> </P><P>then in the implementation of the new method we should be able to access both the header and child entities</P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>METHOD deep_create.
DATA(lv_import) = order.
DATA(lv_import_sr) = serial.
LOOP AT lv_import_sr ASSIGNING FIELD-SYMBOL(<sr>) .
LOOP AT <sr>-%target ASSIGNING FIELD-SYMBOL(<tr>).
wa_order_ser = VALUE #(
%key-production_order = lv_ord_no
%key-serial = <tr>-serial
production_order = lv_ord_no
).
wa_report_ser = VALUE #(
%key-production_order = lv_ord_no
%key-serial = <tr>-serial
production_order = lv_ord_no
).
wa_fail_ser = VALUE #(
%key-production_order = lv_ord_no
%key-serial = <tr>-serial
production_order = lv_ord_no
).
SELECT SINGLE obknr
FROM objk
WHERE sernr EQ @<tr>-serial
AND taser EQ 'SER05'
INTO (obj_list).
ENDLOOP.
ENDLOOP.
ENDMETHOD.</code></pre><P> </P><P> </P><P> </P><P>Finally we create the service binding and service definition</P><P> </P><P> </P><pre class="lia-code-sample language-abap"><code>@EndUserText.label: 'Blocking zrep order type serials'
define service Z7PAPI_ZREP_BLOCK {
expose z7pi_production_order as prd_ord;
expose z7pi_serial_number as serial;
}</code></pre><P> </P><P> </P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Mahmoud_Wael_0-1737544514045.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/215320iD6323D9F434F9C40/image-size/large?v=v2&px=999" role="button" title="Mahmoud_Wael_0-1737544514045.png" alt="Mahmoud_Wael_0-1737544514045.png" /></span></P><P>then we move to testing</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Mahmoud_Wael_1-1737544929653.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/215325iDD5B5B368E9750DC/image-size/large?v=v2&px=999" role="button" title="Mahmoud_Wael_1-1737544929653.png" alt="Mahmoud_Wael_1-1737544929653.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Mahmoud_Wael_2-1737544939552.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/215326i7FE0588AA79FF693/image-size/large?v=v2&px=999" role="button" title="Mahmoud_Wael_2-1737544939552.png" alt="Mahmoud_Wael_2-1737544939552.png" /></span></P><P>as shown you can access your header and child entities however you see fit</P><P> </P>2025-01-24T16:44:09.141000+01:00https://community.sap.com/t5/technology-blogs-by-members/defining-a-basic-cds-view/ba-p/13996477Defining a Basic CDS View2025-01-25T10:58:50.521000+01:00mickaelquesnothttps://community.sap.com/t5/user/viewprofilepage/user-id/150004<DIV class=""><P>Defining a basic Core Data Services (CDS) view in SAP involves creating a data model on the database layer rather than the application layer. This offers significant advantages in terms of performance, data access, and reusability. Here's a breakdown of how to define a basic CDS view:</P><P><STRONG>1. Development Environment:</STRONG></P><P>You'll typically use the ABAP Development Tools (ADT) in Eclipse to create CDS views. This provides a modern and integrated development environment.</P><P><STRONG>2. CDS View Syntax:</STRONG></P><P>The basic syntax for defining a CDS view is as follows:</P><DIV class=""><DIV class=""><SPAN class="">SQL</SPAN><DIV class=""> </DIV></DIV><DIV class=""><DIV class=""><PRE><SPAN class="">@AbapCatalog</SPAN>.sqlViewName: <SPAN class="">'SQL_VIEW_NAME'</SPAN>
<SPAN class="">@AbapCatalog</SPAN>.compiler.compareFilter: <SPAN class="">true</SPAN>
<SPAN class="">@AccessControl</SPAN>.authorizationCheck: #<SPAN class="">CHECK</SPAN>
<SPAN class="">define</SPAN> <SPAN class="">view</SPAN> VIEW_NAME
<SPAN class="">as</SPAN> <SPAN class="">select</SPAN> <SPAN class="">from</SPAN> DATABASE_TABLE <SPAN class="">or</SPAN> <SPAN class="">VIEW</SPAN>
{
element1 <SPAN class="">as</SPAN> alias1,
element2 <SPAN class="">as</SPAN> alias2,
...
elementN <SPAN class="">as</SPAN> aliasN
};</PRE></DIV></DIV></DIV><P>Let's break down each part:</P><UL><LI><STRONG>@AbapCatalog.sqlViewName: 'SQL_VIEW_NAME':</STRONG> This annotation is mandatory. It defines the name of the corresponding SQL view that will be created in the database. This is the name you'll use when accessing the view from standard SQL.</LI><LI><STRONG>@AbapCatalog.compiler.compareFilter: true:</STRONG> This annotation is recommended. It ensures that filter conditions are pushed down to the database level for better performance.</LI><LI><STRONG>@AccessControl.authorizationCheck: #CHECK:</STRONG> This annotation is crucial for security. It enforces authorization checks based on the defined authorization objects.</LI><LI><STRONG>define view VIEW_NAME:</STRONG> This keyword starts the definition of the CDS view, followed by the name you want to give to the CDS entity. This is the name used within ABAP programs.</LI><LI><STRONG>as select from DATABASE_TABLE or VIEW:</STRONG> This specifies the data source for the view. You can select from database tables, database views, or other CDS views.</LI><LI><STRONG>{ element1 as alias1, ... }:</STRONG> This is the element list. It defines the fields you want to include in the view. You can rename fields using aliases (as alias).</LI></UL><P><STRONG>3. Example:</STRONG></P><P>Let's say you have a database table SCARR (Carrier) and you want to create a CDS view that includes the carrier ID and name:</P><DIV class=""><DIV class=""><SPAN class="">SQL</SPAN><DIV class=""> </DIV></DIV><DIV class=""><DIV class=""><PRE><SPAN class="">@AbapCatalog</SPAN>.sqlViewName: <SPAN class="">'Z_CARRIER_VIEW'</SPAN>
<SPAN class="">@AbapCatalog</SPAN>.compiler.compareFilter: <SPAN class="">true</SPAN>
<SPAN class="">@AccessControl</SPAN>.authorizationCheck: #<SPAN class="">CHECK</SPAN>
<SPAN class="">define</SPAN> <SPAN class="">view</SPAN> ZCarrierView
<SPAN class="">as</SPAN> <SPAN class="">select</SPAN> <SPAN class="">from</SPAN> SCARR
{
carrid <SPAN class="">as</SPAN> CarrierID,
carrname <SPAN class="">as</SPAN> CarrierName
};</PRE></DIV></DIV></DIV><P>In this example:</P><UL><LI>Z_CARRIER_VIEW is the name of the SQL view.</LI><LI>ZCarrierView is the name of the CDS view.</LI><LI>carrid is renamed to CarrierID.</LI><LI>carrname is renamed to CarrierName.</LI></UL><P><STRONG>4. Key Concepts and Enhancements:</STRONG></P><UL><LI><STRONG>Aliases:</STRONG> Using aliases makes your code more readable and can be essential when joining tables with fields that have the same name.</LI><LI><STRONG>Data Types:</STRONG> The data types of the elements in the view are derived from the underlying database table or view.</LI><LI><STRONG>Expressions:</STRONG> You can use expressions in the element list to create calculated fields. For example:</LI></UL><DIV class=""><DIV class=""><SPAN class="">SQL</SPAN><DIV class=""> </DIV></DIV><DIV class=""><DIV class=""><PRE><SPAN class="">define</SPAN> <SPAN class="">view</SPAN> ZSalesOrderValue
<SPAN class="">as</SPAN> <SPAN class="">select</SPAN> <SPAN class="">from</SPAN> VBAK
{
vbeln <SPAN class="">as</SPAN> SalesOrder,
netwr <SPAN class="">as</SPAN> NetValue,
waerk <SPAN class="">as</SPAN> Currency,
netwr <SPAN class="">*</SPAN> <SPAN class="">1.19</SPAN> <SPAN class="">as</SPAN> GrossValue <SPAN class="">/</SPAN><SPAN class="">/</SPAN> Calculated field
};</PRE></DIV></DIV></DIV><UL><LI><STRONG>Joins:</STRONG> You can join multiple tables or views in the FROM clause.</LI></UL><DIV class=""><DIV class=""><SPAN class="">SQL</SPAN><DIV class=""> </DIV></DIV><DIV class=""><DIV class=""><PRE><SPAN class="">define</SPAN> <SPAN class="">view</SPAN> ZCustomerOrders
<SPAN class="">as</SPAN> <SPAN class="">select</SPAN> <SPAN class="">from</SPAN> KNA1 <SPAN class="">as</SPAN> Customer
<SPAN class="">inner</SPAN> <SPAN class="">join</SPAN> VBAK <SPAN class="">as</SPAN> SalesOrder
<SPAN class="">on</SPAN> Customer.kunnr <SPAN class="">=</SPAN> SalesOrder.kunnr
{
Customer.kunnr <SPAN class="">as</SPAN> CustomerID,
Customer.name1 <SPAN class="">as</SPAN> CustomerName,
SalesOrder.vbeln <SPAN class="">as</SPAN> SalesOrderNumber
};</PRE></DIV></DIV></DIV><UL><LI><STRONG>WHERE Clause:</STRONG> You can use a WHERE clause to filter the data.</LI></UL><DIV class=""><DIV class=""><SPAN class="">SQL</SPAN><DIV class=""> </DIV></DIV><DIV class=""><DIV class=""><PRE><SPAN class="">define</SPAN> <SPAN class="">view</SPAN> ZActiveCustomers
<SPAN class="">as</SPAN> <SPAN class="">select</SPAN> <SPAN class="">from</SPAN> KNA1
{
kunnr <SPAN class="">as</SPAN> CustomerID,
name1 <SPAN class="">as</SPAN> CustomerName
} <SPAN class="">where</SPAN> kunnr <SPAN class="">like</SPAN> <SPAN class="">'1000%'</SPAN>; <SPAN class="">/</SPAN><SPAN class="">/</SPAN> <SPAN class="">Filter</SPAN> customers starting <SPAN class="">with</SPAN> <SPAN class="">1000</SPAN>
</PRE></DIV></DIV></DIV><UL><LI><STRONG>Associations:</STRONG> You can define associations between CDS views to navigate related data. This is a more advanced topic but very powerful for building complex data models.</LI></UL><P><STRONG>5. Activation and Usage:</STRONG></P><P>After defining the CDS view in ADT, you need to activate it. This creates the corresponding SQL view in the database. You can then use the CDS view in ABAP programs using Open SQL statements:</P><DIV class=""><DIV class=""><SPAN class="">ABAP</SPAN><DIV class=""> </DIV></DIV><DIV class=""><DIV class=""><PRE>SELECT *
FROM ZCarrierView
INTO TABLE @DATA(lt_carriers).</PRE></DIV></DIV></DIV><P>You can also access the underlying SQL view directly using native SQL if needed.</P><P><STRONG>Benefits of CDS Views:</STRONG></P><UL><LI><STRONG>Performance:</STRONG> Data processing is pushed down to the database level, which is much faster than processing data in the application server.</LI><LI><STRONG>Simplified Data Access:</STRONG> CDS views provide a simplified and consistent way to access data.</LI><LI><STRONG>Reusability:</STRONG> CDS views can be reused in multiple applications.</LI><LI><STRONG>Extensibility:</STRONG> You can extend standard SAP data models using CDS views without modifying the original objects.</LI></UL><P>By understanding these basic concepts, you can start building efficient and powerful data models using CDS views in your SAP development.</P><P> </P><P><A title="PDF LINKEDIN" href="https://www.linkedin.com/posts/mickaelquesnot_gusap-s4-hanadefining-a-basic-cds-viewdocx-activity-7288156015299108864-KdWM?utm_source=share&utm_medium=member_desktop" target="_self" rel="nofollow noopener noreferrer">https://www.linkedin.com/posts/mickaelquesnot_gusap-s4-hanadefining-a-basic-cds-viewdocx-activity-7288156015299108864-KdWM?utm_source=share&utm_medium=member_desktop</A></P></DIV>2025-01-25T10:58:50.521000+01:00https://community.sap.com/t5/technology-blogs-by-members/from-syntax-to-semantics-a-classification-of-core-data-services-cds/ba-p/14005981From Syntax to Semantics: A Classification of Core Data Services (CDS)2025-02-06T19:31:06.611000+01:00PrusakouIlyahttps://community.sap.com/t5/user/viewprofilepage/user-id/1769851<DIV class=""><H2 id="toc-hId-1701884000">Table of Contents</H2><OL><LI><STRONG>Introduction</STRONG></LI><LI><STRONG>Topology Layers</STRONG></LI><LI><STRONG>Logical Layer</STRONG></LI><LI><STRONG>CDS Object Tree</STRONG></LI><LI><STRONG>CDS and SQL</STRONG></LI><LI><STRONG>CDS System Function</STRONG></LI><LI><STRONG>CDS Scalar Function and CDS Table Function</STRONG></LI><LI><STRONG>CDS System Entities</STRONG></LI><LI><STRONG>Linguo-Technical Layer</STRONG></LI><LI><STRONG>Mapping CDS Language to CDS Source Code and CDS Object</STRONG></LI><LI><STRONG>Syntactic Layer</STRONG></LI><LI><STRONG>CDS by Keyword</STRONG></LI><LI><STRONG>Keyword Semantic</STRONG></LI><LI><STRONG>Business Layer</STRONG></LI><LI><STRONG>VDM Type</STRONG></LI><LI><STRONG>CDS Purpose</STRONG></LI><LI><STRONG>CDS by Stability Contract</STRONG></LI><LI><STRONG>CDS by Lifecycle</STRONG></LI><LI><STRONG>CDS by Modelling Pattern</STRONG></LI></OL><H2 id="toc-hId-1505370495">1 Introduction</H2></DIV><P>Recently, I read the ABAP keyword documentation to get an overview of the CDS framework from a high-level perspective. I came across numerous terms, each defined in the keyword dictionary. For example, terms like<SPAN> </SPAN><STRONG>CDS Objects</STRONG>,<SPAN> </SPAN><STRONG>DDL</STRONG>, and<SPAN> </SPAN><STRONG>CDS Entity</STRONG><SPAN> </SPAN>were mentioned, among others.</P><P>This prompted me to organize and systematize these terms to better understand their roles and why the documentation authors chose to highlight them.</P><P>As a result, I came up with the idea of creating a CDS classification. Of course, this topology is not exhaustive.</P><P>This article turned out to be quite a long read, and I hope, dear reader, that you won’t mind. Maybe you’ll find a moment to go through this classification while sipping your latte on a winter evening. Otherwise, feel free to use the table of contents above to navigate quickly through the article.</P><P>I’ve only gathered high-level information here, so I encourage you to dive deeper if you're interested.</P><P>If you prefer the article is available on my GitHub: <A href="https://github.com/IlyaPrusakou/CDSClassification.git" target="_blank" rel="noopener nofollow noreferrer">https://github.com/IlyaPrusakou/CDSClassification.git</A></P><DIV class=""><H2 id="toc-hId-1308856990">2 Topology Layers</H2></DIV><P>The CDS typology begins by dividing the CDS framework into four layers:</P><P>1<SPAN> </SPAN><STRONG>Logical</STRONG><BR />2<SPAN> </SPAN><STRONG>Linguo-technical</STRONG><BR />3<SPAN> </SPAN><STRONG>Syntactic</STRONG><BR />4<SPAN> </SPAN><STRONG>Business</STRONG></P><P>The first three layers are derived from the keyword documentation, while the fourth—<STRONG>Business</STRONG>—is based on my experience and active googling.</P><DIV class=""><H2 id="toc-hId-1112343485">3 Logical Layer</H2></DIV><P>At the foundation of the<SPAN> </SPAN><STRONG>Logical level</STRONG><SPAN> </SPAN>is the term<SPAN> </SPAN><STRONG>CDS object</STRONG>. I would define a CDS object as a programmatic entity that encapsulates all runtime properties of a CDS view. We refer to a CDS as an object when it is used as a type in ABAP code, as part of an Open SQL selection, or in similar contexts.</P><DIV class=""><H2 id="toc-hId-915829980">4 CDS Object Tree</H2></DIV><P>I would represent CDS objects as the following tree:</P><P>1<SPAN> </SPAN><STRONG>CDS objects</STRONG></P><P>1.1<SPAN> </SPAN><STRONG>CDS annotations</STRONG></P><P>1.2<SPAN> </SPAN><STRONG>CDS metadata extensions</STRONG></P><P>1.3<SPAN> </SPAN><STRONG>CDS entities</STRONG><BR />1.3.1<SPAN> </SPAN><STRONG>CDS view entities</STRONG><BR />1.3.2<SPAN> </SPAN><STRONG>CDS projections view</STRONG><BR />1.3.2.1<SPAN> </SPAN><STRONG>CDS Transactional query</STRONG><BR />1.3.2.2<SPAN> </SPAN><STRONG>CDS Analytical projection view</STRONG><BR />1.3.2.3<SPAN> </SPAN><STRONG>CDS Transactional interface</STRONG><BR />1.3.3<SPAN> </SPAN><STRONG>CDS Table functions</STRONG><BR />1.3.4<SPAN> </SPAN><STRONG>CDS Hierarchies</STRONG><BR />1.3.5<SPAN> </SPAN><STRONG>CDS Custom Entities</STRONG><BR />1.3.6<SPAN> </SPAN><STRONG>CDS Abstract Entities</STRONG><BR />1.3.7<SPAN> </SPAN><STRONG>CDS DDIC-based views</STRONG><BR />1.3.8<SPAN> </SPAN><STRONG>CDS External Entities</STRONG><BR />1.3.9<SPAN> </SPAN><STRONG>ABAP CDS Aspect</STRONG></P><P>1.4<SPAN> </SPAN><STRONG>CDS Tunning Objects</STRONG><BR />1.4.1<SPAN> </SPAN><STRONG>CDS Entity Buffers</STRONG></P><P>1.5<SPAN> </SPAN><STRONG>CDS User Defined Types</STRONG><BR />1.5.1<SPAN> </SPAN><STRONG>CDS Simple Types</STRONG><BR />1.5.2<SPAN> </SPAN><STRONG>CDS Enumeration Types</STRONG></P><P>1.6<SPAN> </SPAN><STRONG>CDS Functions</STRONG><BR />1.6.1<SPAN> </SPAN><STRONG>CDS Scalar Functions</STRONG><BR />1.6.1.1<SPAN> </SPAN><STRONG>CDS SQL-based Scalar Functions</STRONG><BR />1.6.1.2<SPAN> </SPAN><STRONG>CDS Analytical Scalar Functions</STRONG><BR />1.6.2<SPAN> </SPAN><STRONG>CDS Built-in Functions</STRONG></P><P>1.7<SPAN> </SPAN><STRONG>CDS Roles</STRONG></P><DIV class=""><H2 id="toc-hId-719316475">5 CDS and SQL</H2></DIV><P>Also, it's worth to mention It is also worth mentioning the classification of<SPAN> </SPAN><STRONG>CDS Entities</STRONG><SPAN> </SPAN>into two categories:</P><OL><LI><P><STRONG>CDS SQL Entities</STRONG><SPAN> </SPAN>– This includes all entities except CDS non-SQL entities.</P></LI><LI><P><STRONG>CDS Non-SQL Entities</STRONG><SPAN> </SPAN>– These are specialized entities such as<SPAN> </SPAN><STRONG>Abstract Entities</STRONG>,<SPAN> </SPAN><STRONG>Custom Entities</STRONG>, and<SPAN> </SPAN><STRONG>CDS Analytical Projection Views</STRONG>.</P></LI></OL><DIV class=""><H2 id="toc-hId-522802970">6 CDS System Function</H2></DIV><P>Another important aspect to clarify is the semantic overlap between<SPAN> </SPAN><STRONG>CDS user-defined functions</STRONG><SPAN> </SPAN>and<SPAN> </SPAN><STRONG>CDS system functions</STRONG>. The overarching term for both is<SPAN> </SPAN><STRONG>CDS Scalar Function</STRONG>, which can be further classified as follows:</P><OL><LI><STRONG>CDS Scalar Function</STRONG><BR />1.1<SPAN> </SPAN><STRONG>Analytical Scalar Function</STRONG><SPAN> </SPAN>- Classified as a<SPAN> </SPAN><STRONG>System Function</STRONG><BR />1.2<SPAN> </SPAN><STRONG>SQL-Based Scalar Function</STRONG><BR /> 1.2.1<SPAN> </SPAN><STRONG>Delivered by SAP</STRONG><SPAN> </SPAN>- Classified as a<SPAN> </SPAN><STRONG>System Function</STRONG><BR /> 1.2.2<SPAN> </SPAN><STRONG>User-Defined Scalar Function</STRONG></LI></OL><DIV class=""><H2 id="toc-hId-326289465">7 CDS Scalar Function and CDS Table Function</H2></DIV><P>I would also like to emphasize the dichotomy between<SPAN> </SPAN><STRONG>CDS Table Functions</STRONG><SPAN> </SPAN>and<SPAN> </SPAN><STRONG>CDS Scalar Functions</STRONG>. While<SPAN> </SPAN><STRONG>CDS Table Functions</STRONG><SPAN> </SPAN>are classified as a type of<SPAN> </SPAN><STRONG>CDS Entity</STRONG>,<SPAN> </SPAN><STRONG>CDS Scalar Functions</STRONG><SPAN> </SPAN>fall under the category of<SPAN> </SPAN><STRONG>CDS Functions</STRONG>.</P><DIV class=""><H2 id="toc-hId-129775960">8 CDS System Entities</H2></DIV><P>Lastly, it’s worth noting that SAP provides special<SPAN> </SPAN><STRONG>CDS System Entities</STRONG>, which are predefined entities. However, for the sake of clarity and consistency, I propose classifying them under<SPAN> </SPAN><STRONG>CDS Entities</STRONG>, specifically as entities delivered by SAP.</P><DIV class=""><H2 id="toc-hId--66737545">9 Linguo-Technical Layer</H2></DIV><P>At the core of the<SPAN> </SPAN><STRONG>Technical level</STRONG><SPAN> </SPAN>lies the term<SPAN> </SPAN><STRONG>CDS source code</STRONG>. Why is this significant? The answer is that CDS source code is used by developers to define all the properties of a CDS object. Additionally, it serves for transporting CDS objects between systems and generating the corresponding runtime artifacts.</P><DIV class=""><H2 id="toc-hId-84003307">10 Mapping CDS Language to CDS Source Code and CDS Object</H2></DIV><P>In summary, I propose distinguishing<SPAN> </SPAN><STRONG>CDS objects</STRONG><SPAN> </SPAN>as runtime artifacts and<SPAN> </SPAN><STRONG>CDS source code</STRONG><SPAN> </SPAN>as design-time artifacts. The classification can be outlined as follows:</P><P> </P><TABLE><TBODY><TR><TD width="225.398px" height="30px"><STRONG>Source Code Type</STRONG></TD><TD width="210.795px" height="30px"><STRONG>Source Code Subtype</STRONG></TD><TD width="338.92px" height="30px"><STRONG>CDS Object</STRONG></TD></TR><TR><TD width="225.398px" height="30px"><STRONG>CDS Source Code</STRONG></TD><TD width="210.795px" height="30px"><STRONG>CDS Source Code</STRONG></TD><TD width="338.92px" height="30px"><STRONG>CDS Object</STRONG></TD></TR><TR><TD width="225.398px" height="57px"><STRONG>Data Definition Language (DDL)</STRONG></TD><TD width="210.795px" height="57px"> </TD><TD width="338.92px" height="57px"><STRONG>CDS Entity</STRONG><SPAN> </SPAN>(e.g., CDS View Entity, CDS Custom Entity, etc.)</TD></TR><TR><TD width="225.398px" height="30px"> </TD><TD width="210.795px" height="30px"><STRONG>DDL Annotation (DDLA)</STRONG></TD><TD width="338.92px" height="30px"><STRONG>CDS Annotation</STRONG></TD></TR><TR><TD width="225.398px" height="57px"> </TD><TD width="210.795px" height="57px"><STRONG>DDL Metadata Extension (DDLX)</STRONG></TD><TD width="338.92px" height="57px"><STRONG>CDS Metadata Extension</STRONG></TD></TR><TR><TD width="225.398px" height="57px"><STRONG>Data Control Language (DCL)</STRONG></TD><TD width="210.795px" height="57px"> </TD><TD width="338.92px" height="57px"><STRONG>CDS Roles</STRONG></TD></TR><TR><TD width="225.398px" height="57px"><STRONG>Type Definition Language (TDL)</STRONG></TD><TD width="210.795px" height="57px"> </TD><TD width="338.92px" height="57px"><STRONG>CDS User-Defined Types</STRONG></TD></TR><TR><TD width="225.398px" height="57px"><STRONG>Function Definition Language (FDL)</STRONG></TD><TD width="210.795px" height="57px"> </TD><TD width="338.92px" height="57px"><STRONG>CDS Function</STRONG></TD></TR></TBODY></TABLE><P>I deliberately exclude<SPAN> </SPAN><STRONG>Service Definition Language (SDL)</STRONG>, as it pertains to a different topic—the<SPAN> </SPAN><STRONG>RAP framework</STRONG>. Nevertheless, it’s worth noting the close relationship between Service Definitions and the CDS framework.</P><P>Additionally, it’s important to highlight that the languages used for<SPAN> </SPAN><STRONG>annotations</STRONG><SPAN> </SPAN>and<SPAN> </SPAN><STRONG>metadata extensions</STRONG><SPAN> </SPAN>(<STRONG>DDLA</STRONG><SPAN> </SPAN>and<SPAN> </SPAN><STRONG>DDLX</STRONG>) are sub-dialects of the broader<SPAN> </SPAN><STRONG>DDL</STRONG>.</P><DIV class=""><H2 id="toc-hId--112510198">11 Syntactic Layer</H2></DIV><P>In the<SPAN> </SPAN><STRONG>Syntactic Layer</STRONG>, I am going to propose a classification of CDS entities based on their primary defining keyword. This approach organizes CDS artifacts according to the central syntax element that dictates their structure and functionality. By focusing on the main keyword, we can establish a clear and systematic understanding of the various CDS types.</P><DIV class=""><H2 id="toc-hId--309023703">12 CDS by Keyword</H2></DIV><P><STRONG>1. Syntax of ABAP CDS</STRONG></P><P>1.1<SPAN> </SPAN><STRONG>DEFINE ANNOTATION</STRONG><BR />1.2<SPAN> </SPAN><STRONG>ANNOTATE VIEW</STRONG><BR />1.3<SPAN> </SPAN><STRONG>ANNOTATE ENTITY</STRONG></P><P>1.4<SPAN> </SPAN><STRONG>DEFINE VIEW ENTITY</STRONG></P><P>1.5<SPAN> </SPAN><STRONG>DEFINE VIEW ENTITY AS PROJECTION ON</STRONG><BR /><STRONG>Provide Contract: Transactional Query</STRONG></P><P>1.6<SPAN> </SPAN><STRONG>DEFINE VIEW ENTITY AS PROJECTION ON</STRONG><BR /><STRONG>Provide Contract: Transactional Interface</STRONG></P><P>1.7<SPAN> </SPAN><STRONG>DEFINE TRANSIENT VIEW ENTITY AS PROJECTION ON</STRONG><BR /><STRONG>Provide Contract: Analytical Query</STRONG></P><P>1.8<SPAN> </SPAN><STRONG>DEFINE VIEW</STRONG><BR />1.9<SPAN> </SPAN><STRONG>DEFINE TABLE FUNCTION</STRONG><BR />1.10<SPAN> </SPAN><STRONG>DEFINE HIERARCHY</STRONG><BR />1.11<SPAN> </SPAN><STRONG>DEFINE CUSTOM ENTITY</STRONG><BR />1.12<SPAN> </SPAN><STRONG>DEFINE ABSTRACT ENTITY</STRONG><BR />1.13<SPAN> </SPAN><STRONG>DEFINE EXTERNAL ENTITY</STRONG><BR />1.14<SPAN> </SPAN><STRONG>DEFINE VIEW ENTITY BUFFER</STRONG></P><P>1.15<SPAN> </SPAN><STRONG>DEFINE ROLE</STRONG><BR />1.16<SPAN> </SPAN><STRONG>DEFINE ACCESS POLICY</STRONG></P><P>1.17<SPAN> </SPAN><STRONG>DEFINE TYPE</STRONG><BR />1.18<SPAN> </SPAN><STRONG>DEFINE TYPE ENUM</STRONG></P><P>1.19<SPAN> </SPAN><STRONG>DEFINE SCALAR FUNCTION</STRONG></P><P>1.20<SPAN> </SPAN><STRONG>DEFINE ASPECT</STRONG></P><P>2<SPAN> </SPAN><STRONG>Extension Syntax</STRONG></P><P>2.1<SPAN> </SPAN><STRONG>EXTEND VIEW ENTITY</STRONG><BR />2.2<SPAN> </SPAN><STRONG>EXTEND CUSTOM ENTITY</STRONG><BR />2.3<SPAN> </SPAN><STRONG>EXTEND ABSTRACT ENTITY</STRONG><BR />2.4<SPAN> </SPAN><STRONG>EXTEND VIEW</STRONG></P><DIV class=""><H2 id="toc-hId--505537208">13 Keyword Semantic</H2></DIV><P>To express the semantics of the<SPAN> </SPAN><STRONG>CDS main keyword</STRONG>, I have adopted a notation similar to<SPAN> </SPAN><STRONG>Backus-Naur Form (BNF)</STRONG>, which is commonly used to describe the syntax of programming languages. In this approach, the<SPAN> </SPAN><STRONG>CDS main keyword</STRONG><SPAN> </SPAN>is constructed using the following components:</P><P> </P><pre class="lia-code-sample language-sql"><code><keyword> ::= <cds_action> <cds_type>
<cds_action> ::= define | extend | annotate
<cds_type> ::= view | <entity> | <view_entity> | role | table_function | aspect | hierarchy | <type> | scalar_function | view_entity_buffer
<entity> ::= [custom | abstract | external] entity
<view_entity> ::= [transient] view entity [as projection] [<contract>]
<contract> ::= provide contract transactional {query | interface} | analytical query
<type> ::= type | type enum</code></pre><P> </P><DIV class=""><H2 id="toc-hId--702050713">14 Business Layer</H2></DIV><P>The<SPAN> </SPAN><STRONG>Business Layer</STRONG><SPAN> </SPAN>represents the practical application of CDS as a modeling pillar, enabling the creation of business entities based on the technical foundation provided by the CDS framework. One of the key guides within this layer is the<SPAN> </SPAN><STRONG>Virtual Data Model (VDM)</STRONG>, which standardizes the design and structure of CDS-based entities to align with business requirements.</P><P>VDM acts like a blueprint, similar to how Lego bricks can be assembled to build a castle. In this analogy, the Lego bricks represent the CDS framework components, while the final model—be it a<SPAN> </SPAN><STRONG>Remote API</STRONG>,<SPAN> </SPAN><STRONG>Value Help</STRONG>, or another business construct—symbolizes the resulting business entity. This approach ensures consistency, reusability, and alignment with SAP's overall architecture principles.</P><DIV class=""><H3 id="toc-hId--1191967225">15 VDM Type</H3></DIV><P>The division of the<SPAN> </SPAN><STRONG>Business Layer</STRONG><SPAN> </SPAN>relies on the values of the<SPAN> </SPAN><STRONG>VDM.viewType</STRONG><SPAN> </SPAN>annotation. This annotation is a key component used by SAP for the internal structuring and interpretation of CDS views. It defines the purpose and role of each CDS view within the overall VDM architecture. Below are the specific types of VDM views:</P><P>1<SPAN> </SPAN><STRONG>Basic CDS View</STRONG></P><P>Represents the foundational layer of the VDM. Typically maps to a single database table to provide raw data. Used as a building block for higher-level CDS views.</P><P>2<SPAN> </SPAN><STRONG>Composite CDS View</STRONG></P><P>Combines multiple Basic CDS Views or other Composite Views. Provides aggregated, enriched, or contextualized data. Acts as a middle layer in the VDM hierarchy.</P><P>3<SPAN> </SPAN><STRONG>Consumption CDS View</STRONG></P><P>Designed for use in user interfaces, analytics, or APIs. Focuses on data presentation and consumption by external applications. Often leverages SAP Fiori or analytical tools.</P><P>4<SPAN> </SPAN><STRONG>Extension CDS View</STRONG></P><P>Used to extend existing CDS views without modifying the original definition. Enables custom fields or logic to be added to standard SAP-delivered views.</P><P>5<SPAN> </SPAN><STRONG>Derivation Function</STRONG></P><P>Facilitates the calculation of derived fields or values within a CDS view. They are often used for derivation values for <STRONG>CDS parameters</STRONG>.</P><P>6<SPAN> </SPAN><STRONG>Transactional</STRONG></P><P>Supports transactional use cases. Often used for modelling business objects(e.g. <STRONG>RAP objects</STRONG>) and associated with data modification or interactions in SAP’s transactional scenarios.</P><DIV class=""><H3 id="toc-hId--1388480730">16 CDS Purpose</H3></DIV><P><STRONG>CDS Purpose Classification:</STRONG></P><P>1<SPAN> </SPAN><STRONG>Views Providing Data Access</STRONG></P><P>These views interact with the underlying database and are used for various data access purposes:</P><P>1.1<SPAN> </SPAN><STRONG>Interface CDS View</STRONG></P><P>Acts as an interface for data reading, often used as a source in Open SQL or as select source in other CDS views</P><P>1.2<SPAN> </SPAN><STRONG>Restricted Reuse CDS View</STRONG></P><P>Provides entities with specific restrictions for usage outside of particular application area. Restricted nature means that the CDS should not be used by customers or SAP partners in their developments. Don't confuse with Private CDS.</P><P>1.3<SPAN> </SPAN><STRONG>Consumption CDS View</STRONG></P><P>Focused on presenting data for analytics or user interfaces (e.g., SAP Fiori). Therefore they contain a plenty of consumption specific metadata.</P><P>1.4<SPAN> </SPAN><STRONG>Private CDS View</STRONG></P><P>Intended for internal use as constituting part of other non-private CDS. Once it is created, it is used only in one specific place in CDS hierarchy.</P><P>1.5<SPAN> </SPAN><STRONG>Transactional Processing CDS View</STRONG></P><P>They are used for modelling CDS tree of business objects and enable capability of adding transactional behavior to them.</P><P>1.6<SPAN> </SPAN><STRONG>Remote API CDS View</STRONG></P><P>Exposes data as part of remote APIs for integration with external consumers. While Consumption CDS are created for specific consumption case providing a set consumption specific metadata, Remote API CDS are consumption and client agnostic reducing any redundant metadata.</P><P>1.7<SPAN> </SPAN><STRONG>View Extends</STRONG></P><P>Extends an existing CDS view to add additional fields or logic while keeping the original definition intact.</P><P>1.8<SPAN> </SPAN><STRONG>View Extension Include</STRONG></P><P>Created by key user extensibility supplier to enable this extension option for customers. To better understand this topic, I recommend exploring the<SPAN> </SPAN><STRONG>Key User Extensibility</STRONG><SPAN> </SPAN>documentation. Essentially, these views serve as anchors for further extensions views generated via key user apps</P><P>1.9<SPAN> </SPAN><STRONG>Derivation Function</STRONG></P><P>Performs derived field calculations within the CDS view.</P><P>2<SPAN> </SPAN><STRONG>Views Without Data Access</STRONG></P><P>These views do not directly access data but serve other modeling purposes:</P><P>2.1<SPAN> </SPAN><STRONG>Abstract View</STRONG></P><P>Provides an abstract structure used for ABAP typing and RAP action parameter modelling.</P><DIV class=""><H2 id="toc-hId--1291591228">17 CDS by Stability Contract</H2></DIV><P>By stability contract:</P><P>1<SPAN> </SPAN><STRONG>C0 Extend</STRONG><BR />These entities can be extended, with specific usage contexts:</P><P>1.1<SPAN> </SPAN><STRONG>Use in Key User Apps</STRONG><BR />Extension point is designed for extensions via key user tools.</P><P>1.2<SPAN> </SPAN><STRONG>Use in Cloud Development</STRONG><BR />Extension point is suitable for extensions in cloud-based development scenarios(in <STRONG>ADT tool</STRONG>).</P><P>1.3<SPAN> </SPAN><STRONG>Both context</STRONG><BR />Can be used in both key user apps and cloud development environments.</P><P>2<SPAN> </SPAN><STRONG>C1 Use System-Internally</STRONG><BR />These entities are intended for internal system usage:</P><P>2.1<SPAN> </SPAN><STRONG>Use in Key User Apps</STRONG><BR />View is visible in objects with language version <STRONG>ABAP for Key Users</STRONG>.</P><P>2.2<SPAN> </SPAN><STRONG>Use in Cloud Development</STRONG><BR />View is visible in objects with language version <STRONG>ABAP for Cloud Development</STRONG>.</P><P>3<SPAN> </SPAN><STRONG>C2 Use as Remote API</STRONG><BR />These entities are exposed as remote APIs for external consumption.</P><DIV class=""><H2 id="toc-hId--1488104733">18 CDS by Lifecycle</H2></DIV><P>By lifecycle status:</P><P>1<SPAN> </SPAN><STRONG>Released</STRONG><BR />CDS views that are officially released for productive use. SAP and partner and customers shall utilize them in full grade.</P><P>2<SPAN> </SPAN><STRONG>Deprecated</STRONG><BR />CDS views that are marked for future removal. While still available, successor view is provided to substitute of deprecated one. Their usage is discouraged and all interesting actors have to adopt their code to replace with successor view.</P><P>3<SPAN> </SPAN><STRONG>Decommissioned</STRONG><BR />CDS views that are no longer available or supported. The code adoption is completed. A particular time, usually defined by product owner, for notification of customers is over. They can be removed from the system at any time.</P><DIV class=""><H2 id="toc-hId--1684618238">19 CDS by Modelling Pattern</H2></DIV><P>1<SPAN> </SPAN><STRONG>None</STRONG><BR />Basic CDS views without any specific modeling pattern applied.</P><P>2<SPAN> </SPAN><STRONG>Auxiliary Views</STRONG><BR />These views serve auxiliary purposes, such as supporting additional features or providing helper structures:</P><P>2.1<SPAN> </SPAN><STRONG>Data Structure</STRONG>: These entities are primarily used for parameter modeling in RAP actions or functions and for defining structured variable types in ABAP code. Typically, such CDS entities are not combined with other supported capabilities. Their exlusive purpose is to serve as data structures</P><P>2.2<SPAN> </SPAN><STRONG>Language Dependent</STRONG>:These CDS entities provide translations or language-dependent texts. They are often based on text tables or table with domain values. Typically, they are linked to text consumer entities through associations.</P><P>2.3<SPAN> </SPAN><STRONG>Value Help Provider</STRONG>: These CDS entities are used to supply value help for fields, such as dropdown lists or input assistance. They are typically based on database tables or existing CDS entities that contain the relevant value set. Value help providers are linked to consumer entities through associations and annotations, ensuring seamless integration with user interfaces.</P><P>2.4<SPAN> </SPAN><STRONG>Collective Value Help</STRONG>: It refers to a CDS entity that combines multiple value help sources into a single, unified value help. This is useful when a field requires input assistance from different datasets or when the value help is context-specific.</P><P>2.5<SPAN> </SPAN><STRONG>Derivation Function</STRONG>: It is a mechanism in SAP CDS views used to calculate or derive values dynamically based on specific business logic or conditions. These functions are often used to populate fields, restrict data, or enhance query results by deriving context-specific values, such as defaulting fiscal periods, calculating derived attributes, or mapping inputs to outputs. The CDS entity can be used as Derivation Function in an Consumption.derivation annotation.</P><P>6<SPAN> </SPAN><STRONG>Parent-Child Hierarchy Node Provider</STRONG><BR />Used for hierarchical data structures, enabling navigation between parent and child nodes. The CDS entity defines a parent-child hierarchy. Requests from the entity return hierarchy nodes with additional hierarchy-specific information, for example the size of the subhierarchy starting at a node. The entity can be used in hierarchy-navigation and hierarchy-aggregation functions.</P><P>7<SPAN> </SPAN><STRONG>Enterprise Search Provider</STRONG><BR />These view entities are annotated with framework-specific<SPAN> </SPAN><STRONG>annotations EnterpriseSearch</STRONG>. The annotations define search capabilities and they also trigger the generation of a<SPAN> </SPAN><STRONG>CDS-based search connector</STRONG>. CDS-based enterprise search provides enhanced search capabilities in SAP Fiori launchpad.</P><P>8<SPAN> </SPAN><STRONG>RAP Framework</STRONG><BR />Focused on the SAP RESTful Application Programming model:</P><P>8.1<SPAN> </SPAN><STRONG>Transactional Interface</STRONG>: A CDS transactional interface is a CDS projection view that is intended to serve as<SPAN> </SPAN><STRONG>stable public interface for consumption</STRONG>. A CDS transactional interface should be classified by a<SPAN> </SPAN><STRONG>release contract</STRONG>(don't mixed up with provider contract) and thus serve as<SPAN> </SPAN><STRONG>released API</STRONG>. They are typically used in the context of the ABAP RESTful Application Programming Model to provide the basis for a<SPAN> </SPAN><STRONG>RAP BO interface</STRONG>. Technically,<SPAN> </SPAN><STRONG>BO interface layer</STRONG><SPAN> </SPAN>consists of a<SPAN> </SPAN><STRONG>CDS projection view</STRONG><SPAN> </SPAN>with the<SPAN> </SPAN><STRONG>provider contract transactional_interface</STRONG><SPAN> </SPAN>and a<SPAN> </SPAN><STRONG>Behavior Definition Interface</STRONG><SPAN> </SPAN>with implementation type<SPAN> </SPAN><STRONG>interface</STRONG>. A CDS transactional interface is defined using the CDS DDL statement<SPAN> </SPAN><STRONG>DEFINE VIEW ENTITY AS PROJECTION ON</STRONG><SPAN> </SPAN>and it must have its provider contract set to<SPAN> </SPAN><STRONG>TRANSACTIONAL_INTERFACE</STRONG>. A CDS transactional interface is a CDS persistent entity.</P><P>8.2<SPAN> </SPAN><STRONG>Transactional Query</STRONG>: A CDS projection view that is intended for modeling<SPAN> </SPAN><STRONG>transactional queries</STRONG>. A transactional query is typically used in the context of the ABAP RESTful Application Programming Model to adapt a CDS data model<SPAN> </SPAN><STRONG>for service-specific use cases</STRONG><SPAN> </SPAN>(They are substitution of Consumption views). A transactional query is defined using the CDS DDL statement<SPAN> </SPAN><STRONG>DEFINE VIEW ENTITY AS PROJECTION ON</STRONG><SPAN> </SPAN>and it must have the provider contract set to<SPAN> </SPAN><STRONG>TRANSACTIONAL_QUERY</STRONG>. A CDS transactional query is a CDS persistent entity.</P><P>9<SPAN> </SPAN><STRONG>Analytical Framework</STRONG><BR />Designed for analytics and reporting:</P><P>9.1<SPAN> </SPAN><STRONG>Analytical Query</STRONG>: Analytical queries are views that selects data from your analytical data model, based on specific use-cases requirements. Queries can also define the initial layout that is displayed in the output, and can be used to perform various analytical evaluations and calculations. They expose defined<SPAN> </SPAN><STRONG>measurement</STRONG><SPAN> </SPAN>and<SPAN> </SPAN><STRONG>dimensions</STRONG></P><P>9.2<SPAN> </SPAN><STRONG>Analytical Cube</STRONG>: Data cube represents the multidimensional data model. All fields(except key fields) should be defined as<SPAN> </SPAN><STRONG>dimensions</STRONG><SPAN> </SPAN>or<SPAN> </SPAN><STRONG>measures</STRONG>. The cube view is the center of a<SPAN> </SPAN><STRONG>Star/Snowflake schema</STRONG><SPAN> </SPAN>referencing dimension views (annotated with<SPAN> </SPAN><STRONG>Analytics.dataCategory: #DIMENSION</STRONG>). CDS view as cube view has annotation<SPAN> A</SPAN><STRONG>nalytics.dataCategory: #CUBE</STRONG><SPAN> </SPAN>in the header. A cube is the data source of an analytical query (analytical projection) and must contain<SPAN> </SPAN><STRONG>at least one measure</STRONG>.</P><P>9.3<SPAN> </SPAN><STRONG>Analytical Dimension</STRONG>: A dimension view provides extended information for combination of dimension and measure fields in Cube like<SPAN> </SPAN><STRONG>attributes</STRONG>,<SPAN> </SPAN><STRONG>texts</STRONG>,<SPAN> </SPAN><STRONG>hierarchies</STRONG>. The view is annotated with<SPAN> </SPAN><STRONG>Analytics.dataCategory: #DIMENSION</STRONG></P><P>9.4<SPAN> </SPAN><STRONG>Analytical Parent-Child Hierarchy Node</STRONG>: The CDS entity can be used as a parent-child hierarchy in analytics. It is either an analytical dimension, or connected to an analytical dimension. The rows of the entity represent nodes of the hierarchy. Currently only hierarchies defined by annotation Hierarchy.parentChild can be used in analytic models.</P><P>9.5<SPAN> </SPAN><STRONG>Analytical Document Store</STRONG>: These CDS entities are usually annotated with:<SPAN> <STRONG>O</STRONG></SPAN><STRONG>bjectModel.supportedCapabilities: #ANALYTICAL_DOCUMENT_STORE</STRONG><SPAN> </SPAN>and<SPAN> <STRONG>O</STRONG></SPAN><STRONG>bjectModel.modellingPattern: #ANALYTICAL_DOCUMENT_STORE</STRONG>. Also, they have a specific data category:<SPAN> <STRONG>A</STRONG></SPAN><STRONG>nalytics.dataCategory: #DOCSTORE</STRONG>. Moreover, these CDS entities should be linked with the parent CDS Analytics Cube via the annotation<SPAN> <STRONG>A</STRONG></SPAN><STRONG>nalytics.document.storageForEntity: ['Name_of_Cube']</STRONG>. And last but not least, the annotation<SPAN> </SPAN><STRONG>Analytics.document.serviceClassName: '<IF_RSDOC_SERVICE_VIR>'</STRONG><SPAN> </SPAN>should be placed in the CDS header. A CDS-based Document Store handles Document IDs and their assignment to cells in a query result. The actual documents are handled by the application. To achieve this, the application must implement a class that implements a special interface IF_RSDOC_SERVICE_VIRT, and the name of this class must be assigned to the Document CDS view.</P><P>9.6<SPAN> </SPAN><STRONG>Analytical Fact</STRONG>: Facts are an<SPAN> </SPAN><STRONG>optional</STRONG><SPAN> </SPAN>part of an analytical data model in ABAP analytics. A fact can be used as a<SPAN> </SPAN><STRONG>data source for a cube</STRONG>. The fact view has annotation<SPAN> </SPAN><STRONG>Analytics.dataCategory: #FACT</STRONG><SPAN> </SPAN>in the header</P><P>9.7<SPAN> </SPAN><STRONG>Analytical KPI</STRONG>:The Analytical KPI CDS is designed to represent Key Performance Indicators (KPIs) within SAP's analytical frameworks. KPIs provide measurable values that help organizations assess the performance of their processes, operations, or objectives.</P><P>10<SPAN> </SPAN><STRONG>Output Management</STRONG><BR />Enables data preparation for outputs like forms and emails:</P><P>10.1<SPAN> </SPAN><STRONG>Output Form Data Provider</STRONG>: Supplies data for forms.</P><P>10.2<SPAN> </SPAN><STRONG>Output Email Data Provider</STRONG>: Provides data for email templates.</P><P>10.3<SPAN> </SPAN><STRONG>Output Parameter Determination Data Source</STRONG>: Helps in determining parameters for output processes.</P><P>11<SPAN> </SPAN><STRONG>Situation Framework</STRONG><BR />Handles contextual situations and notifications:</P><P>11.1<SPAN> </SPAN><STRONG>Situation Anchor</STRONG>: Defines the primary anchor business object for a situation.</P><P>11.2<SPAN> </SPAN><STRONG>Situation Trigger</STRONG>: Specifies the events or triggers for a situation.</P><P>11.3<SPAN> </SPAN><STRONG>Situation Data Context</STRONG>: Provides the data context for evaluating situations.</P><P>12<SPAN> </SPAN><STRONG>External Data Provider</STRONG><BR />Integrates data from external sources into the CDS framework. I suppose that pattern is imposed exactly for CDS External Entities.</P><P>It's worth mentioning that for hierarchy modeling, we can also distinguish patterns such as<SPAN> </SPAN><STRONG>hierarchy source CDS</STRONG><SPAN> </SPAN>and<SPAN> </SPAN><STRONG>CDS hierarchy directory</STRONG>. Moreover, CDS hierarchies can be modeled in a<SPAN> </SPAN><STRONG>time-dependent</STRONG><SPAN> </SPAN>or<SPAN> </SPAN><STRONG>permanent</STRONG><SPAN> </SPAN>manner.</P><P>Regarding points 10–11, they remain unfamiliar territory to me. Therefore, I would greatly appreciate it if you, dear reader, could share a detailed guide on them. Thank you in advance!</P><P> </P><P> </P><P> </P>2025-02-06T19:31:06.611000+01:00https://community.sap.com/t5/technology-blogs-by-members/calling-soap-asynchronous-api-in-rap-public-cloud/ba-p/14012118Calling SOAP Asynchronous Api In RAP ( Public Cloud )2025-02-11T14:49:07.721000+01:00Ilayda_Ymlhglhttps://community.sap.com/t5/user/viewprofilepage/user-id/176149<P>Greetings to everyone,</P><P>I recently took part in my first public cloud project. I did a lot of research and development in this process. I would like to share with you a case that happened to me and the steps I applied in this case.</P><P><STRONG>Used Api:</STRONG> Journal Entry - Clearing (Asynchronous) </P><P>( <A href="https://api.sap.com/api/JOURNALENTRYBULKCLEARINGREQUES/overview" target="_blank" rel="noopener noreferrer">https://api.sap.com/api/JOURNALENTRYBULKCLEARINGREQUES/overview</A> )</P><P>Tutorial on the use of SOAP Services:</P><P><A href="https://developers.sap.com/tutorials/abap-environment-soap-web-services..html" target="_blank" rel="noopener noreferrer">https://developers.sap.com/tutorials/abap-environment-soap-web-services..html</A></P><P><STRONG>Case:</STRONG> Journal Entry - Clearing (Asynchronous) api is called with a button behind a screen made using RAP. In this case, when we start with the approach in the tutorial link above, dump is taken on the screen caused by the modify statement in the automatically generated class.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ilayda_Ymlhgl_13-1739180905880.png" style="width: 559px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/224206iA6B1BA1096656062/image-dimensions/559x102?v=v2" width="559" height="102" role="button" title="Ilayda_Ymlhgl_13-1739180905880.png" alt="Ilayda_Ymlhgl_13-1739180905880.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ilayda_Ymlhgl_1-1739180719289.png" style="width: 558px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/224191i4EC99AA48577041B/image-dimensions/558x254?v=v2" width="558" height="254" role="button" title="Ilayda_Ymlhgl_1-1739180719289.png" alt="Ilayda_Ymlhgl_1-1739180719289.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ilayda_Ymlhgl_2-1739180719290.png" style="width: 560px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/224190i563DBF34F3A1546B/image-dimensions/560x133?v=v2" width="560" height="133" role="button" title="Ilayda_Ymlhgl_2-1739180719290.png" alt="Ilayda_Ymlhgl_2-1739180719290.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ilayda_Ymlhgl_3-1739180719290.png" style="width: 557px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/224192i84D4D56A87B5F27A/image-dimensions/557x103?v=v2" width="557" height="103" role="button" title="Ilayda_Ymlhgl_3-1739180719290.png" alt="Ilayda_Ymlhgl_3-1739180719290.png" /></span></P><P>( <A href="https://help.sap.com/docs/abap-cloud/abap-rap/rap-transactional-model-and-sap-luw" target="_blank" rel="noopener noreferrer">https://help.sap.com/docs/abap-cloud/abap-rap/rap-transactional-model-and-sap-luw</A> )</P><P><STRONG>Approach:</STRONG> In this case, we can run the xml of the soap service by embedding it into the body as if we call ODATA service. However, ws-a addressing and generate message id ticks must be checked in order to run Asynchronous Soap services. The aim is to make these ticks behave as if they are checked in postman and to provide the same situation in the code.</P><P>In order to run the Asynchronous SOAP service via SOAPUI, the following two ticks must be checked ( <A href="https://www.soapui.org/docs/soap-and-wsdl/supported-standards/using-ws-addressing/" target="_blank" rel="noopener nofollow noreferrer">https://www.soapui.org/docs/soap-and-wsdl/supported-standards/using-ws-addressing/</A> )</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ilayda_Ymlhgl_14-1739180928235.png" style="width: 596px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/224207iE66BC191EE70E7A9/image-dimensions/596x283?v=v2" width="596" height="283" role="button" title="Ilayda_Ymlhgl_14-1739180928235.png" alt="Ilayda_Ymlhgl_14-1739180928235.png" /></span></P><P>In order for Postman to correspond to this, we need to put the ws-a addressing link that we view in the wsdl file into the header and then fill in the action and message id parts.</P><P><STRONG>Action:</STRONG> We can get the action link on SoapUI.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ilayda_Ymlhgl_5-1739180719292.png" style="width: 534px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/224193i613190F2E4FAF6F2/image-dimensions/534x310?v=v2" width="534" height="310" role="button" title="Ilayda_Ymlhgl_5-1739180719292.png" alt="Ilayda_Ymlhgl_5-1739180719292.png" /></span></P><P><STRONG>WS-A:</STRONG> We can get the link on WSDL.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ilayda_Ymlhgl_6-1739180719292.jpeg" style="width: 538px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/224195i77857D490C832183/image-dimensions/538x105?v=v2" width="538" height="105" role="button" title="Ilayda_Ymlhgl_6-1739180719292.jpeg" alt="Ilayda_Ymlhgl_6-1739180719292.jpeg" /></span></P><P><STRONG>MessageID:</STRONG> urn:uuid:{{{$randomUUUID}}} should be used to structure that generate random uuid with every time we do a post operation.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ilayda_Ymlhgl_16-1739181002688.png" style="width: 635px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/224211i1F259EB3342F41A7/image-dimensions/635x218?v=v2" width="635" height="218" role="button" title="Ilayda_Ymlhgl_16-1739181002688.png" alt="Ilayda_Ymlhgl_16-1739181002688.png" /></span></P><P>We can embed this structure into our transform object when calling the api from our Behavior class. We can use cl_system_uuid=>create_uuid_c36_static( ) method to provide the same format as urn:uuid:{{$randomUUUID}}.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ilayda_Ymlhgl_8-1739180719295.png" style="width: 580px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/224197iA19717EA79E597F7/image-dimensions/580x200?v=v2" width="580" height="200" role="button" title="Ilayda_Ymlhgl_8-1739180719295.png" alt="Ilayda_Ymlhgl_8-1739180719295.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ilayda_Ymlhgl_9-1739180719298.png" style="width: 205px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/224198i7347840BEA8F9B30/image-dimensions/205x37?v=v2" width="205" height="37" role="button" title="Ilayda_Ymlhgl_9-1739180719298.png" alt="Ilayda_Ymlhgl_9-1739180719298.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ilayda_Ymlhgl_10-1739180719298.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/224199i75A2A11D68F84F69/image-size/medium?v=v2&px=400" role="button" title="Ilayda_Ymlhgl_10-1739180719298.png" alt="Ilayda_Ymlhgl_10-1739180719298.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ilayda_Ymlhgl_11-1739180719298.png" style="width: 292px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/224200iB8806FDCFBE6B854/image-dimensions/292x113?v=v2" width="292" height="113" role="button" title="Ilayda_Ymlhgl_11-1739180719298.png" alt="Ilayda_Ymlhgl_11-1739180719298.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ilayda_Ymlhgl_0-1739181866309.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/224218i63B4E379AF0086BD/image-size/medium?v=v2&px=400" role="button" title="Ilayda_Ymlhgl_0-1739181866309.png" alt="Ilayda_Ymlhgl_0-1739181866309.png" /></span></P><P>The code of the Behavior Class Method where the Asynchronous Soap API is called:</P><P> </P><pre class="lia-code-sample language-abap"><code>TRY.
DATA(lo_http_destination) = cl_http_destination_provider=>create_by_url( 'https://host-api.s4hana.cloud.sap/sap/bc/srt/scs_ext/sap/journalentrybulkclearingreques' ).
CATCH cx_http_dest_provider_error INTO DATA(lo_http_dest_provider_error).
ENDTRY.
TRY.
DATA(lo_web_http_client) = cl_web_http_client_manager=>create_by_http_destination( lo_http_destination ) .
CATCH cx_web_http_client_error INTO DATA(lo_client_error).
DATA(lv_client) = lo_client_error->get_text( ).
ENDTRY.
DATA(lo_web_http_request) = lo_web_http_client->get_http_request( ).
lo_web_http_request->set_authorization_basic( EXPORTING i_username = Communication User
i_password = Communication User Password ).
lo_web_http_request->set_header_fields( VALUE #( ( name = 'Content-Type' value = 'text/xml; charset=UTF-8' )
( name = 'SOAPAction' value = 'http://sap.com/xi/SAPSCORE/SFIN/JournalEntryBulkClearingRequest_In/JournalEntryBulkClearingRequest_InRequest' ) ) ).
TRY.
DATA(lv_uuid) = cl_system_uuid=>create_uuid_c36_static( ).
CATCH cx_uuid_error INTO DATA(lx_uuid).
ENDTRY.
lv_uuid_s = lv_uuid.
*--->fill the body
DATA(lv_body) = xco_cp_json=>data->from_abap( ls_body )->apply( VALUE #( ( xco_cp_json=>transformation->underscore_to_pascal_case ) ) )->to_string( ).
TRY.
CALL TRANSFORMATION zfi_ac_api_to
SOURCE data = ls_body
RESULT XML lv_body.
CATCH cx_root INTO DATA(lo_root).
DATA(lv_mes_tr) = lo_root->get_text( ).
ENDTRY.
REPLACE ALL OCCURRENCES OF 'uuid:{UUID}' IN lv_body WITH lv_uuid_s.
REPLACE ALL OCCURRENCES OF '<?xml version="1.0" encoding="utf-16"?>' IN lv_body WITH ''.
REPLACE ALL OCCURRENCES OF '&lt;' IN lv_body WITH '<'.
REPLACE ALL OCCURRENCES OF '&gt;' IN lv_body WITH '>'.
lo_web_http_request->set_text( lv_body ).
TRY.
DATA(lo_web_http_response) = lo_web_http_client->execute( if_web_http_client=>post ).
CATCH cx_web_http_client_error INTO lo_client_error.
lv_client = lo_client_error->get_text( ).
ENDTRY.
DATA(lv_response) = lo_web_http_response->get_text( ).
DATA(ls_response_stat) = lo_web_http_response->get_status( ).</code></pre><P> </P><P>The code of the Transformation Object:</P><P> </P><pre class="lia-code-sample language-abap"><code><xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sap="http://www.sap.com/sapxsl" version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output encoding="UTF-8" indent="yes" method="xml"/>
<xsl:template match="DATA">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sfin="http://sap.com/xi/SAPSCORE/SFIN">
<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsa:Action soapenv:mustUnderstand="1">http://sap.com/xi/SAPSCORE/SFIN/JournalEntryBulkClearingRequest_In/JournalEntryBulkClearingRequest_InRequest</wsa:Action>
<wsa:MessageID soapenv:mustUnderstand="1">uuid:{UUID}</wsa:MessageID>
</soapenv:Header>
<soapenv:Body>
<sfin:JournalEntryBulkClearingRequest>
<xsl:element name="MessageHeader">
<xsl:element name="ID">
<xsl:value-of select="JOURNAL_ENTRY_BULK_CLEARING_RE/MESSAGE_HEADER/I_D"/>
</xsl:element>
<xsl:element name="CreationDateTime">
<xsl:value-of select="JOURNAL_ENTRY_BULK_CLEARING_RE/MESSAGE_HEADER/CREATION_DATE_TIME"/>
</xsl:element>
<TestDataIndicator>
<xsl:value-of select="JOURNAL_ENTRY_BULK_CLEARING_RE/MESSAGE_HEADER/TEST_DATA_INDICATOR"/>
</TestDataIndicator>
</xsl:element>
<JournalEntryClearingRequest>
<xsl:element name="MessageHeader">
<ID>
<xsl:value-of select="JOURNAL_ENTRY_BULK_CLEARING_RE/JOURNAL_ENTRY_CLEARING_REQUEST/MESSAGE_HEADER/I_D"/>
</ID>
<xsl:element name="CreationDateTime">
<xsl:value-of select="JOURNAL_ENTRY_BULK_CLEARING_RE/JOURNAL_ENTRY_CLEARING_REQUEST/MESSAGE_HEADER/CREATION_DATE_TIME"/>
</xsl:element>
</xsl:element>
<JournalEntry>
<CompanyCode>
<xsl:value-of select="JOURNAL_ENTRY_BULK_CLEARING_RE/JOURNAL_ENTRY_CLEARING_REQUEST/JOURNAL_ENTRY/COMPANY_CODE"/>
</CompanyCode>
<AccountingDocumentType>
<xsl:value-of select="JOURNAL_ENTRY_BULK_CLEARING_RE/JOURNAL_ENTRY_CLEARING_REQUEST/JOURNAL_ENTRY/ACCOUNTING_DOCUMENT_TYPE"/>
</AccountingDocumentType>
<DocumentDate>
<xsl:value-of select="JOURNAL_ENTRY_BULK_CLEARING_RE/JOURNAL_ENTRY_CLEARING_REQUEST/JOURNAL_ENTRY/DOCUMENT_DATE"/>
</DocumentDate>
<PostingDate>
<xsl:value-of select="JOURNAL_ENTRY_BULK_CLEARING_RE/JOURNAL_ENTRY_CLEARING_REQUEST/JOURNAL_ENTRY/POSTING_DATE"/>
</PostingDate>
<CurrencyCode>
<xsl:value-of select="JOURNAL_ENTRY_BULK_CLEARING_RE/JOURNAL_ENTRY_CLEARING_REQUEST/JOURNAL_ENTRY/CURRENCY_CODE"/>
</CurrencyCode>
<DocumentHeaderText>
<xsl:value-of select="JOURNAL_ENTRY_BULK_CLEARING_RE/JOURNAL_ENTRY_CLEARING_REQUEST/JOURNAL_ENTRY/DOCUMENT_HEADER_TEXT"/>
</DocumentHeaderText>
<CreatedByUser>
<xsl:value-of select="JOURNAL_ENTRY_BULK_CLEARING_RE/JOURNAL_ENTRY_CLEARING_REQUEST/JOURNAL_ENTRY/CREATED_BY_USER"/>
</CreatedByUser>
<xsl:for-each select="JOURNAL_ENTRY_BULK_CLEARING_RE/JOURNAL_ENTRY_CLEARING_REQUEST/JOURNAL_ENTRY/APARITEMS/item">
<APARItems>
<ReferenceDocumentItem>
<xsl:value-of select="REFERENCE_DOCUMENT_ITEM"/>
</ReferenceDocumentItem>
<CompanyCode>
<xsl:value-of select="COMPANY_CODE"/>
</CompanyCode>
<AccountType>
<xsl:value-of select="ACCOUNT_TYPE"/>
</AccountType>
<APARAccount>
<xsl:value-of select="APARACCOUNT"/>
</APARAccount>
<FiscalYear>
<xsl:value-of select="FISCAL_YEAR"/>
</FiscalYear>
<AccountingDocument>
<xsl:value-of select="ACCOUNTING_DOCUMENT"/>
</AccountingDocument>
<AccountingDocumentItem>
<xsl:value-of select="ACCOUNTING_DOCUMENT_ITEM"/>
</AccountingDocumentItem>
<xsl:value-of select="OTHER_DEDUCTION_AMOUNT_IN_DSP"/>
</APARItems>
</xsl:for-each>
</JournalEntry>
</JournalEntryClearingRequest>
</sfin:JournalEntryBulkClearingRequest>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
</xsl:transform></code></pre><P> </P><P>I hope this blog post has been helpful. </P><P>Have a great day!</P>2025-02-11T14:49:07.721000+01:00