sapui5 - ERP Q&A https://www.erpqna.com/tag/sapui5/ Trending SAP Career News and Guidelines Fri, 21 Nov 2025 06:23:01 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.3 https://www.erpqna.com/wp-content/uploads/2021/11/cropped-erpqna-32x32.png sapui5 - ERP Q&A https://www.erpqna.com/tag/sapui5/ 32 32 My Experience Developing Side-by-Side Applications in SAP BTP for SAP S/4HANA Cloud https://www.erpqna.com/my-experience-developing-side-by-side-applications-in-sap-btp-for-sap-s-4hana-cloud/?utm_source=rss&utm_medium=rss&utm_campaign=my-experience-developing-side-by-side-applications-in-sap-btp-for-sap-s-4hana-cloud Thu, 24 Apr 2025 10:52:43 +0000 https://www.erpqna.com/?p=91684 The architecture I’m sharing here isn’t the only way or necessarily the best approach for every scenario. Rather, it’s the solution I’ve found effective and applied successfully across multiple projects. Why did I choose a Side-by-Side Architecture? I opted for this architecture mainly because it allows me to extend the standard functionalities of SAP S/4HANA […]

The post My Experience Developing Side-by-Side Applications in SAP BTP for SAP S/4HANA Cloud appeared first on ERP Q&A.

]]>
The architecture I’m sharing here isn’t the only way or necessarily the best approach for every scenario. Rather, it’s the solution I’ve found effective and applied successfully across multiple projects.

Why did I choose a Side-by-Side Architecture?

I opted for this architecture mainly because it allows me to extend the standard functionalities of SAP S/4HANA Cloud without directly impacting the ERP core, thus making it easier to maintain a clean core and simplifying the management, maintenance, and evolution of developed applications.

How do I organize SAP BTP?

I usually set up separate subaccounts for each project environment:

  • Development: Where I perform initial testing and functionality development.
  • Quality (Test): Used for integrated testing before final deployment.
  • Production: A stable environment accessed by end users.

This approach has helped me keep things organized, avoid confusion, and significantly simplify the management of BTP services and instances.

Frontend using SAPUI5 and Fiori Elements

My frontend applications are typically developed using SAPUI5 or Fiori Elements, which accelerates development. I deploy these apps in the HTML5 Application Repository and publish them using SAP Build Work Zone, simplifying the management of connections to backend services.

Backend: Choosing between CAP and Java Spring Boot based on needs

For backend development, I divide responsibilities across two main application types, depending on technical requirements and project complexity:

  • CAP (Cloud Application Programming) Applications:
    I use CAP primarily for simpler OData services or functionalities with low concurrency. CAP has been practical for me due to its ease of development and seamless integration with standard SAP services.
  • Java Applications with Spring Boot:
    For scenarios that require complex processing, high concurrency, transactional logic, advanced reporting, or parallel processes, I prefer Java with Spring Boot. This stack consistently delivers excellent performance for demanding scenarios.

Combining these technologies within the same architecture allows me to select the most suitable tool for each specific need, rather than forcing one technology into unsuitable scenarios.

Shared SAP HANA Database

To simplify data management, I typically use a single SAP HANA database shared by both backend application types. A particular choice I make, perhaps less common, is not to use the default HDI infrastructure provided by CAP.

Instead, I manually create a dedicated HANA schema directly accessed by both CAP and Java applications.

This approach has advantages such as simpler database management and easier integration, but it also has some drawbacks, like losing certain automated management features provided by HDI. Still, based on my experience, the benefits have outweighed these disadvantages.

Direct Integration with SAP S/4HANA Cloud

Another critical aspect of my architecture is integration with S/4HANA Cloud. Here, I’ve applied two methods based on backend technology:

  • For Java/Spring Boot, I typically use the SAP S/4HANA Cloud SDK for Java, as it simplifies the connection and management of S/4HANA services significantly.
  • For CAP, I often import EDMX models exposed by S/4HANA Cloud directly, facilitating quick and straightforward integration with standard SAP services.

Both approaches have proven practical and effective in various contexts.

Centralized Authentication with Single Sign-On (SSO)

In most implementations, end users log in using the same authentication they use for S/4HANA Cloud. I achieve this by setting up trust relationships between SAP BTP and the Identity Provider (IDP) used by the ERP. Consequently, once logged into BTP, users can seamlessly interact with S/4HANA Cloud through transparent Single Sign-On (SSO).

This significantly improves the user experience and simplifies access and permission management.

Everything I’ve shared here comes directly from my practical experience implementing real projects. While this isn’t the only method, it’s an architecture I’ve found functional, flexible, and effective. I’m always open to learning from other experiences and alternatives to continuously evolve my approach according to future needs.

Rating: 0 / 5 (0 votes)

The post My Experience Developing Side-by-Side Applications in SAP BTP for SAP S/4HANA Cloud appeared first on ERP Q&A.

]]>
Developing & Deploying the UI5 App to Cloud Foundry and Accessing from App-router End-to-End Steps https://www.erpqna.com/developing-deploying-the-ui5-app-to-cloud-foundry-and-accessing-from-app-router-end-to-end-steps/?utm_source=rss&utm_medium=rss&utm_campaign=developing-deploying-the-ui5-app-to-cloud-foundry-and-accessing-from-app-router-end-to-end-steps Sat, 27 Apr 2024 10:26:02 +0000 https://www.erpqna.com/?p=84440 In this Blog I am going to explain the minimal steps required to setup App router, HTML5 Deployer for the UI5 application to be able to develop and deploy the application to Cloud Foundry Space. We are going to setup destination and consume the same in the UI5 application using App Router. Before Getting started […]

The post Developing & Deploying the UI5 App to Cloud Foundry and Accessing from App-router End-to-End Steps appeared first on ERP Q&A.

]]>
In this Blog I am going to explain the minimal steps required to setup App router, HTML5 Deployer for the UI5 application to be able to develop and deploy the application to Cloud Foundry Space. We are going to setup destination and consume the same in the UI5 application using App Router. Before Getting started Let’s understand the architecture to access the application from Cloud Foundry Space

As you can see in the image attached above, to access the “SAP HTML5 Application Repository Service” we need SAP App Router to be able to fetch the application details and the same is the case for “SAP Destination Service” as well and so on.

The other way is to subscribe to SAP Work-Zone and use the Managed App Router to access the HTML5 application repository and further the Tile can be created for the deployed application to access the same from the Launchpad.

But in this Blog we will not use Work-Zone subscription to access the application instead we will create our own App Router application and deploy the same to the CF Space.

Before proceeding to the development part we will have a quick look into the Pre-Requisites –

  1. Cloud Foundry Space
  2. Northwind Destination in BTP Account
  3. Business Application Studio

Northwind destination details –

As we have the destination in place we can proceed to BAS to start developing our application.

Create a blank folder in the BAS workspace named ui5cfsample. Inside this folder we will create Approuter, HTML5 Deployer and the UI5 application.

Configuring Approuter :-

1. create a new folder approuter inside ui5cfsample project folder.

2. create new file package.json and paste the below code

    {
        "name": "ui5cfsample-approuter",
        "scripts": {
            "start": "node node_modules/@sap/approuter/approuter.js"
        },
        "dependencies": {
            "@sap/approuter": "^9"
        }
    }

    3. create a new file xs-app.json and paste the below code

    {	
      "welcomeFile": "ui5cfsample/index.html",
      "authenticationMethod": "route",
      "routes":[{
        "source":"^/user-api(.*)",
        "target":"$1",
        "service":"sap-approuter-userapi"
      },{
        "source": "^/abap(.*)",
        "target": "$1",
        "destination": "Northwind",
        "authenticationType": "xsuaa"
      }]
    }

    **ui5cfsample/index.html – Whereas ui5cfsample is the application namespace which we will create in later steps.

    **destination – Northwind as we have created the destination in the same name.

    4. create a new file xs-security.json and paste the below code

    {
        "xsappname": "ui5cfsample-xsuaa",
        "tenant-mode": "dedicated",
        "oauth2-configuration": {
            "redirect-uris": [
                "https://ui5cfsample-approuter-*cfapps.us10-001.hana.ondemand.com/login/callback",
                "http://localhost:5001"
            ]
        }
    }

    **login/callback – will redirect the non-logged in user to enter their BTP credentials to continue using the application.

    5. create a new file manifest.yaml and paste the below code

      ---
      applications:
      - name: ui5cfsample-approuter
        buildpacks:
        - https://github.com/cloudfoundry/nodejs-buildpack
        memory: 1GB
        disk_quota: 1GB
        random-route: true
        path:
        services:
        - ui5cfsample-xsuaa
        - ui5cfsample-destination
        - ui5cfsample-html5-runtime

      6. Now in the above manifest.yaml sample code we have 3 services listed which we need to create before deploying the approuter to CF space. Execute the below commands inside approuter folder.

      cf create-service xsuaa application ui5cfsample-xsuaa -c xs-security.json
      cf create-service destination lite ui5cfsample-destination
      cf create-service html5-apps-repo app-runtime ui5cfsample-html5-runtime

      once the services are created you can check those services in Cloud Foundry space –

        **ui5cfsample-html5-host service will be created in the later steps.

        7. Now we have all the listed services in place we can deploy the approuter application to cloud foundry space

          cf push

          Once the application is deployed and running, try launching the approuter application from the Application Route link –

          **When the browser will load the page will come as “Not Found” as the application with namespace ui5cfsample is not yet deployed to Cloud Foundry which we will be doing in the next steps.

          **Now we will check If the metadata is loading from the destination which is maintained. Replace the URL (/ui5cfsample/index.html) with (/abap/V2/OData/OData.svc/$metadata)

          URL – https://<hostname>/abap/V2/OData/OData.svc/$metadata

          Finally, our Approuter application is deployed successfully and working as expected.

          Configuring HTML5 Deployer :-

          1. create a new folder html5-deployer inside ui5cfsample project folder.

          2. create a new file package.json and paste the below code

            {
                "name": "ui5cfsample-html5-deployer",
                "dependencies": {
                    "@sap/html5-app-deployer": "6.2.0"
                },
                "scripts": {
                    "start": "node node_modules/@sap/html5-app-deployer/index.js"
                }
            }

            3. create a new file manifest.yaml and paste the below code

            ---
            applications:
            - name: ui5cfsample-html5-deployer
              buildpacks:
              - https://github.com/cloudfoundry/nodejs-buildpack
              memory: 256MB
              disk_quota: 256MB
              random-route: true
              path:
              services:
              - ui5cfsample-html5-host

            4. As we have one service which is listed and required in the above manifest.yaml file so we will create the service

            cf create-service html5-apps-repo app-host ui5cfsample-html5-host 

            **Now, the setup for html5-deployer is done and we will deploy the application once our UI5 app is ready and the final build of application is copied inside html5-deployer folder.

            Configuring UI5 App :-

            1. We will use the template generator to create a sample freestyle application.

            2. Menu > File > New project from template and fill in the details required and choose the folder location to current ui5cfsample project folder

              3. After the application is generated the folder structure should look like this

              4. create a new file inside webapp folder as xs-app.json and paste the below code

              {	
                "welcomeFile": "index.html",
                "authenticationMethod": "route",
                "routes":[{
                  "source":"^(.*)",
                  "target":"$1",
                  "service":"html5-apps-repo-rt"
                },{
                  "source": "^/abap(.*)",
                  "target": "$1",
                  "destination": "Northwind",
                  "authenticationType": "xsuaa"
                }]
              }

              5. Define the data source & default model in the manifest.json file

              "dataSources": {
                 "mainService": {
                    "uri": "/abap/V2/OData/OData.svc/",
                    "type": "OData"
                }
              }
              
              "": {
                  "dataSource": "mainService",
                  "preload": true
              }

              6. change the source (src) in the index.html with the CDN value

              src=”https://sapui5.hana.ondemand.com/resources/sap-ui-core.js”

              7. Put a List widget and bind the item with Products Entityset to see the data coming from the destination. Open View and paste the below code

                <List
                                headerText="Products"
                                headerLevel="H2"
                                items="{
                                    path: '/Products'
                                }" >
                                <StandardListItem
                                    title="{Name}"
                                    counter="{Rating}"/>
                            </List>

                8. To build the application and put the changes inside html5-deployer folder we need to add a script in package.json file of UI5 app

                "build:ui": "ui5 build --config=ui5.yaml --clean-dest --dest ../html5-deployer/resources/dist"

                9. To build the application execute the below command

                npm run build:ui

                **This command will put the final build inside html5-deployer folder (resources/dist)

                Deploying UI Application :-

                1. We have the final build of the application in the html5-deployer folder (/resources/dist)

                2. Open terminal at html5-deployer location and execute the below command

                  cf push

                  3. Once the html5-deployer application is successfully deployed to the Cloud Foundry space, the UI5 application will be deployed.

                  4. As the application is deployed, Now open the approuter application and access the link, UI5 application should be loading and data should be populated to the List.

                  Now the development & deployment is completed with OData service binding.

                  Rating: 0 / 5 (0 votes)

                  The post Developing & Deploying the UI5 App to Cloud Foundry and Accessing from App-router End-to-End Steps appeared first on ERP Q&A.

                  ]]>
                  Total and Sub-Total of a Table Using Northwind Service in BAS-(Business Application Studio) https://www.erpqna.com/total-and-sub-total-of-a-table-using-northwind-service-in-bas-business-application-studio/?utm_source=rss&utm_medium=rss&utm_campaign=total-and-sub-total-of-a-table-using-northwind-service-in-bas-business-application-studio Sat, 10 Feb 2024 10:45:44 +0000 https://www.erpqna.com/?p=81466 Objective: This blog post provides insights about the Total and Sub-Total of a Numerical Units in a Table using Northwind Service and how to implement in SAP Business Application Studio environment. In this blog post, I’ll demo about Total and Sub-Total of a Numerical Units in a Table using Northwind Service. Northwind Service: Northwind Service […]

                  The post Total and Sub-Total of a Table Using Northwind Service in BAS-(Business Application Studio) appeared first on ERP Q&A.

                  ]]>
                  Objective: This blog post provides insights about the Total and Sub-Total of a Numerical Units in a Table using Northwind Service and how to implement in SAP Business Application Studio environment.

                  In this blog post, I’ll demo about Total and Sub-Total of a Numerical Units in a Table using Northwind Service.

                  Northwind Service: Northwind Service is an OData Sample service and consumed in SAP UI5 and Fiori Applications.

                  Responsive Table: The responsive table automatically adjusts its appearance and behaviour based on the available screen size, making it suitable for both desktop and mobile applications.

                  Use Case: The Total and Sub-total Concept in a table is commonly used in scenarios where you need to display aggregated values for columns like Amount/Prices based on certain criteria like Quantity,Unit ect. For this case i came up with this solution.

                  In this scenario, we’ll assume a simple sales order table with columns like Product, Quantity, Unit and Price.

                  So, let’s get started,

                  Step 1: Creating an Application in Projects Folder

                  • Click on File, “New Project from Template” option.

                  • Select “SAP Fiori application” Template and click on Start Button.

                  • Select “SAP Fiori Worklist Application” Template and click on Next Button.

                  • Select: In Data source- “Connect to System”.

                  In System- “Northwind” Destination.

                  Give Service Path of Northwind Service- “/V2/Northwind/Northwind.svc/”

                  • In Entity Selection,

                  Select: Object Collection- Products Entity Set.

                  Object Collection Key- ProductID Property.

                  Object ID- CategoryID Property.

                  Ater giving all the required details click on the Next Button.

                  • In Project Attributes give required details and click on Finish Button.

                  • Application Created Successfully.

                  Step 2: Developing Application

                  Worklist XML View:

                  • Using Semantic Page Control instead of Native Page.
                  • The SemanticPage control helps in creating a unified page structure for Fiori applications. It includes header content, content area, and a footer, providing a standardized layout for applications.
                  • Give Semantic Page Name Space Library- xmlns:semantic=”sap.m.semantic”.
                  • Implementing Sematic Page as shown in below image:

                  • Added Toolbar Control in Semantic Page and added Three Buttons in it.
                  • Buttons are Total Button, Sub-Total Button and Refresh Button.

                  Output Screen:

                  • Output showing Toolbar with Three Buttons in Semantic Page.

                  • Now let’s add Responsive Table Control for Displaying Products Data.

                  • Added footer in column for displaying the Subtotal for the price.

                  XML CODE SNIPPET:

                  <mvc:View controllerName="com.total.samtotal.controller.Worklist"
                      xmlns="sap.m"
                      xmlns:mvc="sap.ui.core.mvc"
                      xmlns:semantic="sap.m.semantic"
                      xmlns:core="sap.ui.core">
                      <semantic:SemanticPage class="sapUiSizeCompact" id="page" title="{i18n>worklistTitle}" showFooter="false" navButtonPress="onNavBack" showNavButton="false">
                          <semantic:content>
                              <Toolbar>
                                  <ToolbarSpacer />
                                  <Button icon="sap-icon://sum" press="SumList" type="Accept" tooltip="{i18n>Total}"></Button>
                                  <Button id="subTotBtn" icon="sap-icon://add-process" press="openSubTotalFunc" type="Accept" tooltip="{i18n>SubTotal}"></Button>
                                  <Button icon="sap-icon://refresh" press="onTableRefresh" type="Emphasized"></Button>
                              </Toolbar>
                              <Table id="tableSum" width="auto" items="{path: 'ProductModel>/',sorter: {path: 'SupplierID',descending: false}}" noDataText="{i18n>tableNoDataText}" growing="true" growingThreshold="100" growingScrollToLoad="true">
                                  <columns>
                                      <Column width="5%">
                                          <Label text="ID" design="Bold"></Label>
                                      </Column>
                                      <Column >
                                          <Label text="Product Name" design="Bold"></Label>
                                      </Column>
                                      <Column >
                                          <Label text="CategoryID" design="Bold"></Label>
                                      </Column>
                                      <Column >
                                          <Label text="Unit" design="Bold"></Label>
                                          <footer>
                                              <VBox items="{STableModel>/QTYUnit}">
                                                  <Text visible="true" text="{STableModel>}" />
                                              </VBox>
                                          </footer>
                                      </Column>
                                      <Column >
                                          <Label text="Price" design="Bold"></Label>
                                          <footer>
                                              <VBox id="UnitPriceSumId" visible="false" items="{STableModel>/UnitPricetotalVal}">
                                                  <Text text="{path:'STableModel>'}" />
                                              </VBox>
                                          </footer>
                                      </Column>
                                      <Column >
                                          <Label text="Discontinued" design="Bold"></Label>
                                      </Column>
                                  </columns>
                                  <items>
                                      <ColumnListItem >
                                          <customData>
                                              <core:CustomData key="mydata" value="{ProductModel>Flag}" writeToDom="true"></core:CustomData>
                                          </customData>
                                          <cells>
                                              <Text text="{ProductModel>ProductID}"></Text>
                                              <Text text="{ProductModel>ProductName}"></Text>
                                              <Text text="{ProductModel>CategoryID}"></Text>
                                              <Text text="{ProductModel>QuantityPerUnit}"></Text>
                                              <Text text="{ProductModel>UnitPrice}"></Text>
                                              <ObjectStatus text="{ProductModel>Discontinued}" state="{path: 'ProductModel>Discontinued',formatter: '.formatter.status'}" />
                                          </cells>
                                      </ColumnListItem>
                                  </items>
                              </Table>
                          </semantic:content>
                      </semantic:SemanticPage>
                  </mvc:View>

                  Getting Northwind Serivce Data:

                  • In Life Cycle Method- onInit() Function just give the Read Call for Products Entity of Northwind Service.
                  • Read Call for Products Entity Set from Northwind service.
                  • In Read Call we just Split the QuantityPerUnit Property.
                  • We just show QuantityPerUnit property Units without Value in the column.

                  Controller Code:

                  sap.ui.define([
                      "./BaseController",
                      "sap/ui/model/json/JSONModel",
                      "../model/formatter",
                      "sap/ui/model/Filter",
                      "sap/ui/model/FilterOperator",
                      "sap/ui/model/Sorter"
                  ], function (BaseController, JSONModel, formatter, Filter, FilterOperator, Sorter) {
                      "use strict";
                  
                      return BaseController.extend("com.total.samtotal.controller.Worklist", {
                  
                          formatter: formatter,
                  
                          /* =========================================================== */
                          /* lifecycle methods                                           */
                          /* =========================================================== */
                  
                          /**
                           * Called when the worklist controller is instantiated.
                           * @public
                           */
                          onInit: function () {
                              var oViewModel, that = this;
                              // Model used to manipulate control states
                              oViewModel = new JSONModel({
                                  worklistTableTitle: this.getResourceBundle().getText("worklistTableTitle")
                              });
                              this.setModel(oViewModel, "worklistView");
                              that.onGetService();
                          },
                          onGetService: function () {
                              var that = this;
                              var TableModel = new JSONModel();
                              that.getView().setModel(TableModel, "STableModel");
                  
                              //Read Call
                              var oDataHeader = this.getOwnerComponent().getModel();
                              oDataHeader.read("/Products", {
                                  success: function (oData, res) {
                                      var sArray = []
                                      var sData = oData.results;
                                      for (var i = 0; i < oData.results.length; i++) {
                  
                                          var oQtySplit = sData[i].QuantityPerUnit.split(/(\d+)/);
                                          var oQty = oQtySplit[oQtySplit.length - 1].toUpperCase();
                  
                                          var sObj = {};
                                          sObj.CategoryID = sData[i].CategoryID;
                                          sObj.Discontinued = sData[i].Discontinued;
                                          sObj.ProductID = sData[i].ProductID;
                                          sObj.ProductName = sData[i].ProductName;
                                          sObj.QuantityPerUnit = oQty;
                                          sObj.ReorderLevel = sData[i].ReorderLevel;
                                          sObj.SupplierID = sData[i].SupplierID;
                                          sObj.UnitPrice = parseFloat(sData[i].UnitPrice).toFixed(2);
                                          sObj.UnitsInStock = sData[i].UnitsInStock;
                                          sObj.UnitsOnOrder = sData[i].UnitsOnOrder;
                                          sArray.push(sObj);
                                      }
                                      var ProductModel = new JSONModel(sArray);
                                      ProductModel.setSizeLimit(sArray.length);
                                      that.getView().setModel(ProductModel, "ProductModel");
                                  }
                              });
                          },
                  
                  
                      });
                  });

                  Output Screen:

                  • Here we can see only Units in Units Column without value and price.

                  Total Button Logic:

                  • Now can see Code of Total Sum for the Unit and Price Columns in Table.
                  • Here “SumList” Function is an event of Total Button in Toolbar of XML view.

                  Controller Code:

                  //**************************** Sum List Fields Dialog *****************************//
                          SumList: function () {
                              var that = this;
                  
                              var oPricePath = "UnitPrice";
                              var oUnit = "QuantityPerUnit";
                              var oData = [];
                              var oTable = that.byId("tableSum");
                              var uniqueQuantityUnit = [];
                              oTable.getItems().filter(function (item) {
                                  var oPath = item.getBindingContextPath();
                                  var oContext = oTable.getModel("ProductModel").getProperty(oPath);
                                  oData.push(oContext);
                                  if (uniqueQuantityUnit.indexOf(oContext[oUnit]) === -1) {
                                      uniqueQuantityUnit.push(oContext[oUnit]);
                                  }
                              });
                              that.getView().getModel("STableModel").setProperty("/QTYUnit", uniqueQuantityUnit);
                              var oTotalArray = [];
                              for (var i = 0; i < uniqueQuantityUnit.length; i++) {
                                  var sArray = that.onTotalUnitQtyData(uniqueQuantityUnit[i], oData, oPricePath, oUnit);
                                  oTotalArray.push(sArray);
                              }
                              that.byId(oPricePath + "SumId").setVisible(true);
                              that.getView().getModel("STableModel").setProperty("/" + oPricePath + "totalVal", oTotalArray);
                              that.getView().getModel("STableModel").setProperty("/sTotalPath", oPricePath);
                              var sumMsg = "Sum Calculated";
                              sap.m.MessageToast.show(sumMsg);
                          },
                          onTotalUnitQtyData: function (unitQty, oData, oPricePath, unit) {
                              var oTotal = 0;
                              for (var i = 0; i < oData.length; i++) {
                                  if (unitQty === oData[i][unit]) {
                                      var stData = oData[i][oPricePath];
                                      var oValue = parseFloat(stData);
                                      oTotal += oValue;
                                  }
                              }
                              var oMainTotal = parseFloat(oTotal).toFixed(2);
                              return oMainTotal;
                          },

                  Output Screen:

                  • Click on The Total Button to see the Total of Unit &Price in Custom footer of Table.

                  Sub-Total Button Logic:

                  • Now can see Code of Sub-Total Sum for the Unit and Price Columns in Table.
                  • Here “openSubTotalFun” Function is an event of Sub-Total Button in Toolbar of XML view.

                  Controller Code:

                  //**************************** Sum Sub Total List Fields Dialog *****************************//
                          openSubTotalFunc: function () {
                              var that = this;
                              // CategoryID is field with which we do subtotal functionality in table
                              var fieldName = "CategoryID";
                              var oPricePath = "UnitPrice";
                              var oView = that.getView();
                              var oTable = oView.byId("tableSum");
                              var unique = [], oData = [];
                              var qty = 0;
                              oTable.getItems().filter(function (item) {
                                  var oPath = item.getBindingContextPath();
                                  var oContext = oTable.getModel("ProductModel").getProperty(oPath);
                                  oData.push(oContext);
                                  if (unique.indexOf(oContext[fieldName]) === -1) {
                                      unique.push(oContext[fieldName]);
                                  }
                              });
                              unique.forEach(function (uniqVal) {
                                  var sObj = {};
                                  for (var i = 0; i < oTable.getItems().length; i++) {
                                      var sPath = oTable.getItems()[i].getBindingContextPath();
                                      var sContext = oTable.getModel("ProductModel").getProperty(sPath);
                                      if (uniqVal === sContext[fieldName]) {
                                          qty = that.onTotalUnitQtyData(uniqVal, oData, oPricePath, fieldName);
                                          sObj[oPricePath] = qty;
                                      }
                                  }
                                  sObj[fieldName] = uniqVal;
                                  if (sObj[fieldName] === uniqVal) {
                                      sObj.Flag = "LightOrange";
                                  }
                                  oData.splice(oData.length, 0, sObj);
                                  oTable.getModel("ProductModel").setData(oData);
                                  oTable.getModel("ProductModel").setSizeLimit(oData.length);
                                  oTable.getModel("ProductModel").refresh();
                                  oTable.getBinding("items").sort(new Sorter(fieldName, false));
                                  qty = 0;
                              });
                          }

                  CSS Code for Table row Colour:

                  tr[data-mydata="LightOrange"]{
                      background: #FFD898 !important;
                      }
                  tr[data-mydata="None"]{
                      background: #f7f7f7 !important;
                  }

                  Output Screen:

                  • Click on the Sub-Total Button for Displaying Sub-Totals of Price in Custom Footer of Table.

                  Refresh Button Logic:

                  • Click on the Refresh Button to Refresh/Clear Totals and Sub-Total in Table.

                  Controller Code:

                  /*** Event handler for refresh event/ Refreshing Table */
                          onTableRefresh: function () {
                              var that = this;
                              that.onGetService();
                          },

                  Output Screen:

                  Conclusion:

                  We had seen how to do Total and Sub-Total of Units with Values in a Table using Northwind Service.

                  NOTE: Displaying Table data using Northwind Service.

                  Rating: 0 / 5 (0 votes)

                  The post Total and Sub-Total of a Table Using Northwind Service in BAS-(Business Application Studio) appeared first on ERP Q&A.

                  ]]>
                  S/4Hana 2023 – Key User Extensibility – Custom Logic App – Keep the Core Clean https://www.erpqna.com/s-4hana-2023-key-user-extensibility-custom-logic-app-keep-the-core-clean/?utm_source=rss&utm_medium=rss&utm_campaign=s-4hana-2023-key-user-extensibility-custom-logic-app-keep-the-core-clean Tue, 02 Jan 2024 10:54:49 +0000 https://www.erpqna.com/?p=80668 With S/4hana 2023 SAP introduce another fiori application which can help key users to implement BADI’s that have been released by SAP. We can start implementing from the Custom Logic app or from the UI adaptation in an application that can be extended. BADI’s Extension can be created by using the application and we will […]

                  The post S/4Hana 2023 – Key User Extensibility – Custom Logic App – Keep the Core Clean appeared first on ERP Q&A.

                  ]]>
                  With S/4hana 2023 SAP introduce another fiori application which can help key users to implement BADI’s that have been released by SAP. We can start implementing from the Custom Logic app or from the UI adaptation in an application that can be extended.

                  BADI’s Extension can be created by using the application and we will also have the flexibilities to view the latest documents, Develop extension where we can also refer sample code , Test the code and compare the code as well. This app can play a major role to keep the core clean.

                  By using fiori app itself extension can be done.

                  Custom Logic – F6970

                  Custom Logic Fiori App tile in Fiori launchpad –

                  Create Extension –

                  Extension Points

                  Really good Documentation in order to get detailed knowledge of selected BADI.

                  Documentation

                  Create Extension Points.

                  Open Code Editor – This is really nice features.

                  Develop –

                  This is really good right? we have option to see Sample Code.

                  Save and Publish the changes.

                  Test –

                  Compare –

                  Created Extensions project would be added and available in Implementations list .

                  Rating: 0 / 5 (0 votes)

                  The post S/4Hana 2023 – Key User Extensibility – Custom Logic App – Keep the Core Clean appeared first on ERP Q&A.

                  ]]>
                  Unlocking Possibilities: Extending Fiori Elements Apps with the Flexible Programming Model https://www.erpqna.com/unlocking-possibilities-extending-fiori-elements-apps-with-the-flexible-programming-model/?utm_source=rss&utm_medium=rss&utm_campaign=unlocking-possibilities-extending-fiori-elements-apps-with-the-flexible-programming-model Sat, 23 Dec 2023 09:58:11 +0000 https://www.erpqna.com/?p=80480 Introduction Welcome to the world of extending SAP Fiori elements OData V4 apps using the Flexible Programming Model. This model offers a hassle-free approach to expanding app functionalities. Whether you prefer coding in SAPUI5 or utilizing our new building blocks, you’ll find ample ways to customize your apps with ease. In this blog, I’ll provide […]

                  The post Unlocking Possibilities: Extending Fiori Elements Apps with the Flexible Programming Model appeared first on ERP Q&A.

                  ]]>
                  Introduction

                  Welcome to the world of extending SAP Fiori elements OData V4 apps using the Flexible Programming Model. This model offers a hassle-free approach to expanding app functionalities. Whether you prefer coding in SAPUI5 or utilizing our new building blocks, you’ll find ample ways to customize your apps with ease. In this blog, I’ll provide an overview of the flexible programming model and guide you to the relevant documentation.

                  Summary

                  In this blog, you’ll learn how the Flexible Programming Model simplifies extending SAP Fiori Elements apps. We’ll explore customization options, from basic SAPUI5 coding to leveraging new building blocks. By the end, you’ll have a clear understanding of how to adapt apps effortlessly while discovering resources for further exploration.

                  Pre-requisites:

                  • S/4 HANA System
                  • Sap Fiori Elements App (OData V4)
                  • VSCode with SAP Fiori Tools – Extension Pack
                  • Extension Points
                    • Custom Form Element
                    • Custom Filter
                  • Building Blocks
                    • Table
                  • Controller Extensions
                    • Edit Flow

                  Extension Points

                  Extension points in the Flexible Programming Model act like customizable slots in SAP Fiori Elements apps. They let you easily add your own custom elements—sections, actions, form elements, filters, header facets, table columns, and even entirely new pages—just like in Fiori elements for OData V2. But now, you can even seamlessly integrate whole new pages into your app’s navigation flow, giving you the freedom to personalize your app experience in unique ways.

                  Here are some examples:

                  Custom Form Element

                  Custom form element let you easily add your own unique elements to forms wherever you need in SAP Fiori Elements apps like below.

                  SAP Fiori Elements, SAPUI5, OData

                  First, we need change manifest.json

                  //..
                  "ActivitySetObjectPage": {
                      "type": "Component",
                      "id": "ActivitySetObjectPage",
                      "name": "sap.fe.templates.ObjectPage",
                      "options": {
                          "settings": {
                              "editableHeaderContent": false,
                              "controlConfiguration": {
                                  "@com.sap.vocabularies.UI.v1.FieldGroup#General": {
                                      "fields": {
                                          "customFormElementIdentification1": {
                                              "template": "activity.list.report.ext.fragment.CustomField",
                                              "label": "Custom Form Element",
                                              "position": {
                                                  "placement": "After",
                                                  "anchor": "DataField::be_invoiced"
                                              }
                                          }
                                      }
                                  }
                              }
                          }
                      }
                  }
                  //..

                  In this code, our custom field will come from webapp/ext/fragment/CustomField.fragment.xml which has the label ‘Custom Form Element’ and is placed after the be_invoiced field. We should put our code block just below of ‘editableHeaderContent: false’. ‘activity.list.report’ is a namespace. FieldGroup#General is facet which we located our field.

                  Lastly, we will create CustomField.fragment.xml in webapp/ext/fragment/.

                  <core:FragmentDefinition
                      xmlns:core="sap.ui.core"
                      xmlns="sap.m"
                      xmlns:macros="sap.fe.macros"
                  >
                      <Switch
                          id="checkBoxOption2"
                          enabled="{ui>/isEditable}"
                          state="{be_invoiced}"
                          type="AcceptReject"
                      />
                  </core:FragmentDefinition>

                  There are two important points. First, the binding field that we want for our custom component and managing the edit status of this component with binding necessary UI properties.

                  Custom Filter

                  Custom filters in the Flexible Programming Model allow you to add personalized filters to refine data exactly how you need in SAP Fiori Elements apps.

                  SAP Fiori Elements, SAPUI5, OData

                  We need to change the manifest.json.

                  //...
                  "ActivitySetList": {
                    "type": "Component",
                    "id": "ActivitySetList",
                    "name": "sap.fe.templates.ListReport",
                    "options": {
                        "settings": {
                            "contextPath": "/ActivitySet",
                            "variantManagement": "Page",
                            "navigation": {
                                "ActivitySet": {
                                    "detail": {
                                        "route": "ActivitySetObjectPage"
                                    }
                                }
                            },
                            "controlConfiguration": {
                  						"@com.sap.vocabularies.UI.v1.SelectionFields": {
                  							"showClearButton": true,
                  							"filterFields": {
                  								"activity_time": {
                  									"label": "Activity Time",
                  									"template": "activity.list.report.ext.fragment.CustomFilter",
                  									"availability": "Default",
                  									"position": {
                  										"placement": "After",
                  										"anchor": "activity_date"
                  									}
                  								}
                  							}
                  						}
                  					}
                          }
                      }
                  },
                  //...
                  

                  Our custom filter will come from webapp/ext/fragment/CustomFilter.fragment.xml which has label ‘Activity Time’ and placed After activity_date field with ‘Default’ availability. This custom field for ‘activity_time’ field. We should put our code block inside of settings of List Report Page. ‘activity.list.report’ is namespace.

                  Now, we will create CustomFilter.fragment.xml in webapp/ext/fragment/.

                  <core:FragmentDefinition
                      xmlns:core="sap.ui.core"
                      xmlns="sap.m"
                  >
                      <HBox
                          id="_IDGenHBox1234"
                          alignItems="Center"
                          width="100%"
                          core:require="{handler: 'activity/list/report/ext/controller/CustomFilter'}"
                      >
                          <StepInput
                              id="_IDGenStepInput1"
                              value="{path: 'filterValues>', type: 'sap.fe.macros.filter.type.Value', formatOptions: { operator: 'LE' }}"
                              min="0"
                              max="8"
                              step="2"
                              width="100px"
                          />
                          <core:Icon
                              id="_IDGenIcon113212"
                              src="sap-icon://reset"
                              press="handler.onReset"
                              class="sapUiSmallMarginBegin"
                          />
                      </HBox>
                  </core:FragmentDefinition>

                  We have js file to handle press event of reset button. core:require tag in HBox connects our js file to our view. Please note that, we must change dots to slashs in our namespace like that ‘activity.list.report’ to ‘activity/list/report’. Here is CustomFilter.js that is located in webapp/ext/controller.

                  sap.ui.define(
                      ["sap/ui/model/Filter"],
                      function (Filter) {
                          "use strict";
                  
                          return {
                              onReset: function (oEvent) {
                                  this.setFilterValues("activity_time");
                              }
                          };
                      }
                  );

                  Building Blocks

                  Building blocks, distinct from extension points, serve as reusable elements essential in constructing SAP Fiori elements apps. These components, integral to the app’s template, ensure a standardized approach while simplifying development. They’re orchestrated consistently by the framework, ensuring automatic compliance with SAP Fiori standards, including functionalities like draft handling and side effects. Leveraging these building blocks streamlines app extension, promising enduring and easily maintainable software.

                  Table

                  I added the table building block to my custom section, boosting my app’s features but you can also use this building block in your custom fiori app. You can use it directly in your own app without much hassle. The cool part? Table building block is also customizable as you can see I added new custom column. It’s a handy feature that makes app development easier and more consistent, giving your app an instant functionality boost.

                  <macros:Table
                          contextPath="/ActivitySet"
                          metaPath="to_today/@com.sap.vocabularies.UI.v1.LineItem"
                          id="LineItemTable"
                          headerVisible="false"
                          readOnly="true"
                          enableAutoColumnWidth="true"
                      >
                          <macros:columns>
                              <macrosTable:Column
                                  id="_IDGenColumn1"
                                  header="Activity Time/Day"
                                  importance="High"
                                  width="10em"
                                  key="FirstColumnKey"
                              >
                                  <mc:HarveyBallMicroChart
                                      id="_IDGenHarveyBallMicroChart1"
                                      size="XS"
                                      total="8"
                                      totalScale="hr"
                                  >
                                      <mc:items>
                                          <mc:HarveyBallMicroChartItem
                                              id="_IDGenHarveyBallMicroChartItem1"
                                              fraction="{activity_time}"
                                              color="Good"
                                              fractionScale="hr"
                                          />
                                      </mc:items>
                                  </mc:HarveyBallMicroChart>
                              </macrosTable:Column>
                          </macros:columns>
                      </macros:Table>

                  ContextPath is your entity name if you want to use entity directly just make metaPath=”@com.sap.vocabularies.UI.v1.LineItem” and you can add custom column and bind easily as below.

                  Controller Extensions

                  Controller Extensions in SAP Fiori elements offer a set of internally used extensions, exposing overrideable methods that provide developers with added flexibility in customizing app behaviors.

                  Edit Flow

                  The edit flow functionality empowers you to efficiently manage crucial object page events, such as before save, before discard, after edit, and after save, within your Fiori Elements app.

                  SAP Fiori Elements, SAPUI5, OData

                  First, we need to add these code block to our manifest.json under sap.ui5 to extend controller for ObjectPage.

                  //..
                  "sap.ui5": {
                  	"extends": {
                  		"extensions": {
                  			"sap.ui.controllerExtensions": {
                  				"sap.fe.templates.ObjectPage.ObjectPageController": {
                  					"controllerName": "activity.list.report.ext.OPExtend"
                  				}
                  			}
                  		}
                  	},
                  //..

                  Then we need to create OPExtend.controller.js under webapp/ext. We will handle every event in edit flow in that js.

                  sap.ui.define(
                      [
                          "sap/ui/core/mvc/ControllerExtension",
                          "sap/m/Dialog",
                          "sap/m/DialogType",
                          "sap/m/Text",
                          "sap/m/Button",
                          "sap/m/ButtonType",
                          "sap/m/MessageToast",
                          "sap/m/MessageBox"
                      ],
                      function (ControllerExtension, Dialog, DialogType, Text, Button, ButtonType, MessageToast, MessageBox) {
                          "use strict";
                  
                          return ControllerExtension.extend("activity.list.report.ext.OPExtend", {
                              // this section allows to extend lifecycle hooks or override public methods of the base controller
                              override: {
                                  onInit: function () { },
                                  editFlow: {
                                      onBeforeSave: function (mParameters) {
                                          var sTodayDate = new Date().toISOString().split('T')[0];
                                          return this._createDialog("Activity Date will be changed with today's date.").then(() => {
                                              mParameters.context.setProperty('activity_date', sTodayDate)
                                          });
                                      }
                                  },
                              },
                              _createDialog: async function (sText, mParameters) {
                                  return new Promise(function (fnResolve, fnReject) {
                                      var oApproveDialog = new Dialog({
                                          type: DialogType.Message,
                                          title: "Confirm",
                                          content: new Text({ text: sText }),
                                          beginButton: new Button({
                                              type: ButtonType.Emphasized,
                                              text: "Continue",
                                              press: function () {
                                                  oApproveDialog.close();
                                                  fnResolve();
                                              }
                                          }),
                                          endButton: new Button({
                                              text: "Cancel",
                                              press: function () {
                                                  oApproveDialog.close();
                                                  fnReject();
                                              }
                                          }),
                                          escapeHandler: (pCloseDialog) => {
                                              pCloseDialog.resolve();
                                              fnReject();
                                          }
                                      });
                                      oApproveDialog.open();
                                  });
                              }
                          });
                      }
                  );
                  

                  This code allows you to change activity date with today’s date before save event.

                  Remember, Guided Development is another valuable tool that streamlines your app creation at various stages. It’s a powerful aid in making your development process smoother and more efficient.

                  Rating: 0 / 5 (0 votes)

                  The post Unlocking Possibilities: Extending Fiori Elements Apps with the Flexible Programming Model appeared first on ERP Q&A.

                  ]]>
                  Deploying Fiori/UI5 Projects to S/4HANA On-Premise ABAP server via VSCode https://www.erpqna.com/deploying-fiori-ui5-projects-to-s-4hana-on-premise-abap-server-via-vscode/?utm_source=rss&utm_medium=rss&utm_campaign=deploying-fiori-ui5-projects-to-s-4hana-on-premise-abap-server-via-vscode Wed, 23 Aug 2023 14:14:28 +0000 https://www.erpqna.com/?p=76998 In this blog post, I’d like to guide you step by step process of deployment the Fiori/UI5 application to S/4 HANA On-Promise ABAP Repository via Visual Studio Code (VS Code). Before we were deploying our projects via SE38 program with /UI5/UI5_REPOSITIRY_LOAD. We were choosing the Upload Check Box, giving the name, package and description of […]

                  The post Deploying Fiori/UI5 Projects to S/4HANA On-Premise ABAP server via VSCode appeared first on ERP Q&A.

                  ]]>
                  In this blog post, I’d like to guide you step by step process of deployment the Fiori/UI5 application to S/4 HANA On-Promise ABAP Repository via Visual Studio Code (VS Code).

                  Before we were deploying our projects via SE38 program with /UI5/UI5_REPOSITIRY_LOAD.

                  SAP Fiori, SAP ABAP Development, SAP Fiori for SAP ERP, SAP Fiori Tools, SAPUI5

                  We were choosing the Upload Check Box, giving the name, package and description of our application and uploading it to the SAP Server.

                  SAP Fiori, SAP ABAP Development, SAP Fiori for SAP ERP, SAP Fiori Tools, SAPUI5

                  SAP Fiori, SAP ABAP Development, SAP Fiori for SAP ERP, SAP Fiori Tools, SAPUI5

                  Now we are using Visual Studio Code (VSCode) and we have another way to deploy our projects to the ABAP Server.

                  First we are opnening new terminal.

                  SAP Fiori, SAP ABAP Development, SAP Fiori for SAP ERP, SAP Fiori Tools, SAPUI5

                  Selecting our project and writing npm run build.

                  SAP Fiori, SAP ABAP Development, SAP Fiori for SAP ERP, SAP Fiori Tools, SAPUI5

                  npm run build
                  
                  SAP Fiori, SAP ABAP Development, SAP Fiori for SAP ERP, SAP Fiori Tools, SAPUI5

                  VS Code creating dist folder for us in the root.

                  SAP Fiori, SAP ABAP Development, SAP Fiori for SAP ERP, SAP Fiori Tools, SAPUI5

                  We are setting uploder for our project with command “npm install nwabap-ui5uploader –save-dev”.

                  npm install nwabap-ui5uploader --save-dev
                  
                  SAP Fiori, SAP ABAP Development, SAP Fiori for SAP ERP, SAP Fiori Tools, SAPUI5

                  Now we need to create .nwabaprc file in the root folder with properties :

                  SAP Fiori, SAP ABAP Development, SAP Fiori for SAP ERP, SAP Fiori Tools, SAPUI5

                  {
                      "base": "./dist",
                      "conn_usestrictssl" : false,
                      "conn_server": "http://<hostname>:<port>/",
                      "conn_client" : "client",
                      "conn_user": "UserName",
                      "conn_password": "Password",
                      "abap_package": "$TMP",
                      "abap_bsp": "ZDEMO_APP",
                      "abap_bsp_text": "UI5 Deployment Demo"
                  }

                  Then we are changing or adding package.json file “deploy”: “npx nwabap upload” setting.

                  SAP Fiori, SAP ABAP Development, SAP Fiori for SAP ERP, SAP Fiori Tools, SAPUI5

                  "deploy": "npx nwabap upload",

                  As a last step we are writing Run Command “npm run deploy” to console.

                  npm run deploy
                  
                  SAP Fiori, SAP ABAP Development, SAP Fiori for SAP ERP, SAP Fiori Tools, SAPUI5

                  Now you can go to the SAP GUI and run your application to control with Tcode : SE80.

                  SAP Fiori, SAP ABAP Development, SAP Fiori for SAP ERP, SAP Fiori Tools, SAPUI5
                  Rating: 0 / 5 (0 votes)

                  The post Deploying Fiori/UI5 Projects to S/4HANA On-Premise ABAP server via VSCode appeared first on ERP Q&A.

                  ]]>
                  Filter in Function import using oData and UI5 https://www.erpqna.com/filter-in-function-import-using-odata-and-ui5/?utm_source=rss&utm_medium=rss&utm_campaign=filter-in-function-import-using-odata-and-ui5 Thu, 08 Jun 2023 10:40:08 +0000 https://www.erpqna.com/?p=75300 I am writing this blog for beginners on how to filter the data using function Import in SAP UI5 using OData which will be helpful for both front end and back end developer. Function imports are used to do the GET and POST operations for the requirements, which are not possible by the standard operations […]

                  The post Filter in Function import using oData and UI5 appeared first on ERP Q&A.

                  ]]>
                  I am writing this blog for beginners on how to filter the data using function Import in SAP UI5 using OData which will be helpful for both front end and back end developer.

                  Function imports are used to do the GET and POST operations for the requirements, which are not possible by the standard operations available in OData.

                  Sometimes we may want to filter the data based on names or city(non key value), that time we can use function import.

                  We will implement the function import code inside EXECUTE_ACTION method by redefining this method in the DPC Extension class.

                  Steps to create Function Import as follows.

                  First we will create function import in odata.

                  Step1:- Create a table. Use t-code se11

                  
CREATING A TABLE
                  CREATING A TABLE
                  enter the info

                  here we will create field and we will give data element.

                  click on data element of phone.

                  click yes

                  here you have to give domain name.

                  here give data type name and no. of character

                  then activate it.

                  Table

                  we have to go to enhancement category

                  click on more—extras— click on Enhancement category.

                  enhancement of data
                  select data class

                  now activate the table.

                  After this, Enter the data in table.

                  more—utilities—table content—create entries.

                  table entries
                  table data

                  Step 2:- Go to SEGW and create a new project.

                  Give project name and save in local object or package.

                  project created
                  now your project will look like this

                  Step 3:- Right click on Data Model and select import and then select DDIC structure.

                  Give Name and table name and click next.

                  Select table name and click next

                  select is Key and click on finish.

                  now generate runtime artifacts.

                  runtime artifacts generated

                  Step 4:- Right Click on data model, select create and then click on function import.

                  runtime artifacts generated

                  Give Function import name and click on continue.

                  Fill like this.
                  Now project look like this .

                  Click on function import folder and fill the following.

                  What you want to search you can give the Name.

                  After this, generate runtime artifacts.

                  Step 5:- Click on DPC_EXT and redine EXECUTE_ACTION.

                  Write this code in execute_action method.

                  Come back to segw.

                  Click on Service maintanence and register. Give Local and select continue and then select Local package.

                  After this, Click on SAP Gateway client and select yes.

                  Step 6:- Give Function Import name followed by what you want to display the data

                  Here I have given Designation=’DEVELOPER’.

                  So only developer data will be visible.

                  This is about oData function import.

                  —————————————————————————————————————————-

                  Function Import using UI5 in VS code

                  if you have not installed vs code, install vs code and node js.

                  open vs code— click on view—then command palette—then explore and install generator.

                  install all generator

                  Step 1:- Create new project(click on view—then command palette—click on fiori: open application generator).

                  select basic

                  Step 2:- Select service of function import.

                  data source as connect to a system.

                  system:- destination configuration

                  service as segw function import service.

                  click on next.

                  Give View name and project name and click on finish.

                  After this project template will be generated.

                  step 3:- First we will create a json model to store the data.

                  click on model—create a file as data.json

                  json model

                  Configure in manifest.json

                  Here “data” is named model.

                  step 4:- in View.

                  view name is Home.view.xml

                  Here I have used Select control to select the key and table to display the data based on selection.

                  <mvc:View xmlns:core="sap.ui.core" controllerName="functionimport.controller.Home"
                  xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
                  <App >
                  <Page id="page" title="{i18n>title}">
                  <customHeader>
                  <Bar >
                   <contentLeft>
                  <Label />
                  <Title text="Designation"/>
                  <Select selectedKey="SELECT" id="designationsearchid" change="onPress">
                  <items>
                  <core:Item text="-----Select one------" key="SELECT"></core:Item>
                  <core:Item text="DEVELOPER" key="DEVELOPER"></core:Item>
                  <core:Item text="TESTER" key="TESTER"></core:Item>                            
                  </items>
                  </Select>
                  </contentLeft>
                  </Bar>
                  </customHeader>
                  <content>
                  <Table items="{data>/}">
                  <columns>
                      <Column >
                      <Text text="NAME"></Text>
                      </Column>
                      <Column >
                      <Text text="EMAIL"></Text>
                      </Column>
                      <Column >
                       <Text text="PHONE"></Text>
                      </Column>
                      <Column >
                      <Text text="AGE"></Text>
                      </Column>
                      <Column >
                      <Text text="DESIGNATION"></Text>
                      </Column>
                      </columns>
                          <items>
                             <ColumnListItem >
                                <cells>
                                  <Text text="{data>Name}"></Text>
                                </cells>
                  
                                <cells>
                                   <Text text="{data>Email}"></Text>
                                </cells>
                  
                                 <cells>
                                    <Text text="{data>Phone}"></Text>
                                 </cells>
                  
                                 <cells>
                                    <Text text="{data>Age}"></Text>
                                  </cells>
                  
                                  <cells>
                                    <Text text="{data>Designation}"></Text>
                                  </cells>
                  
                              </ColumnListItem>
                           </items>
                        </Table>
                  
                              
                          </content>
                      </Page>
                     </App>
                  </mvc:View>

                  step 5:- in Controller

                  controller name :-Home.controller.js

                  in controller first we should get the selected key, and get the model.

                  Then we have to use callFunction where we need to give entityset, method and urlparameters.

                  onPress:function(){
                                  debugger
                    var selectedKey=this.getView().byId("designationsearchid").getSelectedKey()
                                  var oModel=this.getView().getModel('data')
                                  var oContext=this;
                                  var oDataModel=this.getOwnerComponent().getModel()
                                  var arr=new Array();
                  
                                  oDataModel.callFunction(
                                      "/ZAP_FunctionDemo", {
                                          method:"GET",
                                          urlParameters:{
                                              DESIGNATION:selectedKey
                                          },
                                          success:function(oData,response){
                  
                                              arr=oData.results
                  
                                              oModel.setData(arr)
                                              oContext.getView().setModel(oModel);
                                              debugger
                                          },
                                          error:function(oError)
                                          {
                  
                                          }
                                      }
                                  );
                              }
                          });

                  ————————————output——————————–

                  run the program in terminal using npm start.

                  output view
                  on select of developer
                  on select of tester
                  Rating: 0 / 5 (0 votes)

                  The post Filter in Function import using oData and UI5 appeared first on ERP Q&A.

                  ]]>
                  SAP Fiori Standard App configuration in Launchpad: Manage Purchase Orders (Version 2) https://www.erpqna.com/sap-fiori-standard-app-configuration-in-launchpad-manage-purchase-orders-version-2/?utm_source=rss&utm_medium=rss&utm_campaign=sap-fiori-standard-app-configuration-in-launchpad-manage-purchase-orders-version-2 Sat, 03 Jun 2023 10:48:37 +0000 https://www.erpqna.com/?p=75170 Link to Fiori Apps Library: Manage Purchase Orders (Version 2) https://fioriappslibrary.hana.ondemand.com/sap/fix/externalViewer/#/detail/Apps(‘F0842A’)/S22OP This demo is mainly for the beginners who are curious to learn SAP Fiori Launchpad Configurations. Check for the installations under implementation information tab in SAP Fiori Apps Library. As we all know, we can see for the above installed front end and backend […]

                  The post SAP Fiori Standard App configuration in Launchpad: Manage Purchase Orders (Version 2) appeared first on ERP Q&A.

                  ]]>
                  Link to Fiori Apps Library: Manage Purchase Orders (Version 2)

                  https://fioriappslibrary.hana.ondemand.com/sap/fix/externalViewer/#/detail/Apps(‘F0842A’)/S22OP

                  This demo is mainly for the beginners who are curious to learn SAP Fiori Launchpad Configurations.

                  Check for the installations under implementation information tab in SAP Fiori Apps Library.

                  As we all know, we can see for the above installed front end and backend components in gateway system.

                  Activate the below nodes in SICF and OData Service in n/iwfnd/maint_service

                  Now open Launchpad Designer using tcode: /n/UI2/FLPD_CUST from gateway system. This opens the browser.

                  Create a custom catalog.

                  Open the Technical Catalog: SAP_TC_PRC_COMMON from Fiori Apps Library in Launchpad Designer and create a reference wrt tiles and target mappings to the above custom catalog.

                  Verify the added tiles and target mappings in the custom catalog:

                  Create a custom group and select the required tile:

                  Make sure to capture the Catalog & Group in Customizing TR

                  You need to have the front and backend roles assigned with the custom catalog and group to your user ID by Security team.

                  SAP Fiori Launchpad Output:

                  Rating: 0 / 5 (0 votes)

                  The post SAP Fiori Standard App configuration in Launchpad: Manage Purchase Orders (Version 2) appeared first on ERP Q&A.

                  ]]>
                  End to End UI5 application on SAP BTP https://www.erpqna.com/end-to-end-ui5-application-on-sap-btp/?utm_source=rss&utm_medium=rss&utm_campaign=end-to-end-ui5-application-on-sap-btp Mon, 01 May 2023 11:34:14 +0000 https://www.erpqna.com/?p=74311 The blog will take you through all the steps required to deploy a client and server side application on SAP BTP. Pre-requisites: Login/Register on the SAP BTP platform SAP Business Technology Platform (formerly Cloud Foundry) is a PaaS offered by SAP to host your on-premise applications on cloud. To get started, login or register to […]

                  The post End to End UI5 application on SAP BTP appeared first on ERP Q&A.

                  ]]>
                  The blog will take you through all the steps required to deploy a client and server side application on SAP BTP.

                  Pre-requisites:

                  • Basic knowledge of UI5
                  • Basic node-express knowledge

                  Login/Register on the SAP BTP platform

                  SAP Business Technology Platform (formerly Cloud Foundry) is a PaaS offered by SAP to host your on-premise applications on cloud. To get started, login or register to the same using the below url:

                  https://account.hana.ondemand.com/#/home/welcome

                  Once you login for the first time, you should be able to see the below prompt appear.

                  Select “Continue to Trial Home”.

                  Next, you should see the following pop-up appear.

                  I will select Singapore as that’s the server closest to my current location and click on “Create Account”. The account creation takes a while, you should be able to see the below screen eventually.

                  Once you click “Continue”, you should be able to see the BTP Home Screen.

                  Click on “Go To Your Trial Account”. You will be redirected to a new url. Bookmark this for future use.

                  A “trial” sub-account was already created while creating our account. We will create our own.

                  Click on “Create”–>Subaccount. In the pop up that appears, give your sub-account some meaningful name and select the “US East AWS region”. Hit “Create”.

                  Create Cloud Foundry Environment

                  SAP BTP offers 2 environments to host/manage application viz. Cloud Foundry and Kyma. We will be using Cloud Foundry here. Go inside the newly created sub-account and click on “Enable Cloud Foundry”. Nothing needs to be changed in the pop up that follows. Hit “Create”.

                  Once enabled, we will need to create a “space” to deploy our application.

                  Click on “Create Space” and give it some meaningful name. Now your BTP platform is ready to have applications deployed onto it.

                  Install Cloud Foundry CLI

                  Download the package for your respective OS from below URL and install the same on your local machine. We will be using cloud foundry cli to push our applications to btp.

                  https://github.com/cloudfoundry/cli/wiki/V6-CLI-Installation-Guide

                  Once installed, open cmd and run cf –help. If installed properly, you should be able to see a list of available commands.

                  The Application

                  Our application will consist of 3 layers:

                  • Database: PostgreSql
                  • Business Logic: Node Js
                  • UI: UI5

                  Provisioning the database

                  Inside your subaccount, click on Service Marketplace and search for “PostgreSql”.

                  Come back to cmd and login to your cloud foundry account using “cf login -a https://api.cf.us10-001.hana.ondemand.com/”. Provide your username and password which was used to create the btp account.

                  Create an instance of postgresql using the following command: “cf create-service postgresql-db trial my-post-db-02”. Here “postgresql-db” is the name of the service, “trial” is the service plan and “my-post-db-02” is the instance name. The instance creation takes about 10 mins. Once completed, run the command “cf services” and you should be able to see the service listed for your account.

                  Creating the Node backend application

                  Now that our database instance is provisioned, we need to create our backend node application and bind the same to our database service.

                  Before initializing our node project, we will need to update our postgre service with a tag name which will be used by our node application to identify and bind to the service.

                  Open cmd and run the following command: cf update-service my-post-db-02 -t “my-post-db-02”

                  Create a new Node application using the “npm init -y” command. The main challenge here is to establish binding with the postgre service. We will be using the @sap/xsenv node module to achieve this.

                  Below is the dbConn.js file.

                  const promise = require('bluebird')
                  const xsenv = require('@sap/xsenv')
                  //const env = require('../default-env.json')
                  
                  const optionsDbPromise = {
                      promiseLib: promise
                  }
                  const pgp = require('pg-promise')(optionsDbPromise)
                  
                  var conn_service = {}
                  
                  try {
                      //let envCredentials = env.VCAP_SERVICES['my-postgre-db'][0].credentials
                  
                      xsenv.loadEnv()
                      const envCredentials = xsenv.getServices({
                          "my-post-db-02": { "tag": "my-post-db-02" }
                      })["my-post-db-02"]
                  
                      conn_service.host = envCredentials.hostname
                      conn_service.port = envCredentials.port
                      conn_service.database = envCredentials.dbname
                      conn_service.user = envCredentials.username
                      conn_service.password = envCredentials.password
                      conn_service.ssl = {
                          rejectUnauthorized: false,
                          ca: envCredentials.sslrootcert
                      }
                  
                  } catch (error) {
                      console.log('error')
                  }
                  
                  console.log(conn_service)
                  
                  const db = pgp(conn_service)
                  
                  db.func('version')
                      .timeout(2000)
                      .then((data) => {
                          console.log('DB connection success ', data)
                      }).catch((error) => {
                          console.log(error)
                      })
                  
                  module.exports = {
                      db,
                      pgp
                  }

                  Above we are fetching our “my-post-db-02” service details using the tag filter which we updated earlier. Once these details are fetched, a db connection is created using the hostname, port, ssl root certificate, db name, username and password details for the service. The db instance is exported to be used in other files.

                  Next we need to write the apis which will directly interact with the db. Here we will only showcase creating a table, inserting data, fetching data and updating a record.

                  Below is our apis.js file.

                  const { db } = require("./dbConn")
                  
                  const setupDB = (req, res, db, pgp) => {
                      const QueryFile = pgp.QueryFile
                  
                      db.any(new QueryFile('./lib/sqlSetup.sql'), [])
                          .then(data => {
                              res.status(200).send({ "message": "DB setup successful" })
                          }).catch(error => {
                              res.status(500).send({ "message": error })
                          })
                  }
                  
                  const getAllData = (req, res, db) => {
                      return db.any("select * from ORGANIZATION_MGT.USER_LIST")
                          .then(data => {
                              res.status(200).send({ "message": data })
                          }).catch(error => {
                              res.status(500).send({ "message": error })
                          })
                  }
                  
                  const updateUserData = (req, res, db) => {
                      const id = req.params.id.toString()
                      const location = req.query.location
                      console.log('-------------------------------------------Request----------------------------------------')
                      console.log(req)
                      return db.any(`update ORGANIZATION_MGT.USER_LIST set baselocation='${location}' where id='${id}'`)
                          .then(data => {
                              res.status(200).send({ "message": `User ${id} base location updated successfully!` })
                          }).catch(error => {
                              res.status(500).send({ "message": error })
                          })
                  }
                  
                  module.exports = {
                      setupDB,
                      getAllData,
                      updateUserData
                  }

                  In the above file we have used a sqlSetup.sql file which is used to setup the table schema and insert data first time. Below is the script for the same.

                  CREATE SCHEMA IF NOT EXISTS ORGANIZATION_MGT;
                  
                  DROP TABLE IF EXISTS ORGANIZATION_MGT.USER_LIST;
                  CREATE TABLE ORGANIZATION_MGT.USER_LIST( id VARCHAR(10) NOT NULL PRIMARY KEY, username VARCHAR(40), designation VARCHAR(20), baselocation VARCHAR(20) );
                  INSERT INTO ORGANIZATION_MGT.USER_LIST VALUES ( '835825', 'Archisman', 'SCON', 'Pune' ), ( '835826', 'Anuj', 'LCON', 'Nagpur' ), ( '835827', 'Vaishali', 'LCON', 'Pune' ), ( '835828', 'Ritwika', 'LCON', 'Pune' );

                  Now we will setup the routes in our index.js file which is the entry point of our application. Below is the code for the same.

                  const express = require('express')
                  const cors = require('cors')
                  const { setupDB, getAllData, updateUserData } = require('./lib/apis')
                  const { db, pgp } = require('./lib/dbConn')
                  
                  const app = express()
                  app.use(cors(), (req, res, next) => {
                      next()
                  })
                  app.use(express.json())
                  const port = process.env.PORT || 3000
                  
                  app.post('/setup', (req, res) => {
                      setupDB(req, res, db, pgp)
                  })
                  
                  app.get('/users', (req, res) => {
                      getAllData(req, res, db)
                  })
                  
                  app.post('/users/:id', (req, res) => {
                      updateUserData(req, res, db)
                  })
                  
                  app.listen(process.env.PORT || 3000, () => {
                      console.log(`App is running on port ${port}`)
                  })

                  Next, we will need to create the manifest.yaml file which consists of some essential information required by cloud foundry while creating the application in btp. Below is the code for the same.

                  applications:
                  - name: demo-node-app-01
                    memory: 512M
                    path: ./
                    buildpack: nodejs_buildpack
                    health-check-type: port
                    services:
                      - my-post-db-02

                  Upon creation of all the above files, this is how my project structure looks.

                  Deploying the Node application to BTP

                  Now that we have created our node application locally, it is time to push it to the cloud. Open cmd and navigate to the location where the manifest.yaml file (for the same node app) is location.

                  Run “cf push”. This will push the application to BTP and you should be able to see a route generated as shown below.

                  As a further check run the command “cf logs <app-name>–recent”. You should be able to see that the connection to the postgre service was successfully established.

                  Testing our apis using POSTMAN

                  Now that our backend is established, we should test our apis using postman before integrating with the client side application.

                  We have 3 rest end points to test.

                  • POST /setup
                  • GET /users
                  • POST /users/:id?location

                  Below are snapshots for the same in postman.

                  Integrate api with client side application

                  Once we are satisfied that the apis are working properly, we can go ahead and integrate them to our client side application. I have provided the controller and view code snippet below showcasing the same.

                  sap.ui.define([
                  	'sap/ui/core/mvc/Controller',
                  	'sap/ui/model/json/JSONModel',
                  	'sap/m/MessageBox'
                  ], function (Controller, JSONModel, MessageBox) {
                  	"use strict";
                  
                  	var oController
                  	return Controller.extend("Sample.Quickstart.controller.View1", {
                  		onInit: async function () {
                  			oController = this
                  			const oUserModel = new JSONModel()
                  			oController.getView().setModel(oUserModel, 'oUserModel')
                  			const sUrl = `https://demo-node-app-01.cfapps.us10-001.hana.ondemand.com/users`
                  			await oUserModel.loadData(sUrl, {}, true, 'GET')
                  		},
                  		_onUpdateLocation: async (oEvent) => {
                  
                  			const sPath = oEvent.getSource().getBindingContext('oUserModel').sPath
                  			const oUserModel = oController.getView().getModel('oUserModel')
                  
                  			const id = oUserModel.getProperty(`${sPath}/id`)
                  			const location = oUserModel.getProperty(`${sPath}/baselocation`)
                  
                  			try {
                  				const oUserUpdateModel = new JSONModel()
                  				const sUrl = `https://demo-node-app-01.cfapps.us10-001.hana.ondemand.com/users/${id}?location=${location}`
                  				const oParams = {
                  					location
                  				}
                  
                  				await oUserUpdateModel.loadData(sUrl, oParams, true, 'POST')
                  
                  				MessageBox.success(oUserUpdateModel.getData()['message'])
                  
                  			} catch (error) {
                  				MessageBox.error(error.message)
                  			}
                  		}
                  	});
                  });
                  <mvc:View controllerName="Sample.Quickstart.controller.View1"
                  	xmlns:mvc="sap.ui.core.mvc" displayBlock="true"
                  	xmlns="sap.m">
                  	<App id="app">
                  		<pages>
                  			<Page id="page" title="Org Data" titleAlignment="Center">
                  				<content>
                  					<Table items="{oUserModel>/message}">
                  						<columns>
                  							<Column>
                  								<Label text="User Id" design="Bold"/>
                  							</Column>
                  							<Column>
                  								<Label text="Name" design="Bold"/>
                  							</Column>
                  							<Column>
                  								<Label text="Designation" design="Bold"/>
                  							</Column>
                  							<Column>
                  								<Label text="Location" design="Bold"/>
                  							</Column>
                  						</columns>
                  						<ColumnListItem>
                  							<cells>
                  								<Text text="{oUserModel>id}"/>
                  								<Text text="{oUserModel>username}"/>
                  								<Text text="{oUserModel>designation}"/>
                  								<HBox>
                  									<Input width="80%" value="{oUserModel>baselocation}"/>
                  									<Button type="Emphasized" text="Udpdate" press="_onUpdateLocation"/>
                  								</HBox>
                  							</cells>
                  						</ColumnListItem>
                  					</Table>
                  				</content>
                  			</Page>
                  		</pages>
                  	</App>
                  
                  </mvc:View>

                  Before pushing this application to the cloud, we once again need to create a manifest.yaml file to help cloud foundry with the deployment. Below is the code for the same.

                  applications:
                  - name: demo-ui5-app-01
                    memory: 512M
                    path: ./
                    buildpack: staticfile_buildpack

                  The project structure now looks as below.

                  Pushing the client side application to cloud

                  In the same manner that we deployed our node application, open cmd and navigate to the location where the manifest.yaml file is situated.

                  Run “cf push”. Again a route will be generated for the application as shown below.

                  Now run the route in your browser and you should be able to see your application up and running. (Please note the /webapp/index.html that has been appended to the above route in the screenshot below)

                  Rating: 0 / 5 (0 votes)

                  The post End to End UI5 application on SAP BTP appeared first on ERP Q&A.

                  ]]>
                  Deploy the UI5 Fiori app on SAP ABAP repository with BAS & WEBIDE, create Fiori app Tile using Launchpad Designer https://www.erpqna.com/deploy-the-ui5-fiori-app-on-sap-abap-repository-with-bas-webide-create-fiori-app-tile-using-launchpad-designer/?utm_source=rss&utm_medium=rss&utm_campaign=deploy-the-ui5-fiori-app-on-sap-abap-repository-with-bas-webide-create-fiori-app-tile-using-launchpad-designer Sat, 25 Feb 2023 11:16:42 +0000 https://www.erpqna.com/?p=72336 In this blog we will learn How to deploy the Ui5 Fiori app on SAP ABAP repository with BAS & WEBIDE, also learn about fiori app tile creation in launchpad designer. What is SAP UI5 SAP ui5 is a framework, it consists of Libraries. Used for Creating responsive apps. Fiori Launchpad SAP Fiori launchpad is […]

                  The post Deploy the UI5 Fiori app on SAP ABAP repository with BAS & WEBIDE, create Fiori app Tile using Launchpad Designer appeared first on ERP Q&A.

                  ]]>
                  In this blog we will learn How to deploy the Ui5 Fiori app on SAP ABAP repository with BAS & WEBIDE, also learn about fiori app tile creation in launchpad designer.

                  What is SAP UI5

                  SAP ui5 is a framework, it consists of Libraries. Used for Creating responsive apps.

                  Fiori Launchpad

                  SAP Fiori launchpad is a shell that hosts SAP Fiori apps, and provides the apps with services such as navigation, personalization, embedded support, and application configuration.

                  Fiori launchpad is responsive because it adapts the layout in the Device Screen.

                  Prerequisites

                  1. User must have access to SAP Logon.
                  2. User must have access of TCodes: SE80, /ui2/flp, /ui2/flpd_cust, /ui2/FLPD_CONF, /ui2/_FLPCM_CUST, /ui2/FLCM_CONF, /ui2/semobj, PFCG
                  3. You access to SAP BTP Cockpit.

                  Deploy the Fiori app using Business application Studio (BAS)

                  SAP Business application studio is a cloud based developer tool to develop UI based applications

                  1. Launch the BAS from Cloud cockpit

                  2. Select your desired project –> open the Terminal –> Go to the Project Dir (cd project dir) –> run the command ‘npm run deploy-config’ or ‘npx fiori add deploy-config’.

                  3. Give the required information

                  Choose the Target –> ABAP

                  Select the Destination (If destination is not created, create a destination on SAP BTP Cockpit)

                  Provide the SAPUI5 ABAP Repository Name and Description.

                  Provide the Package detail

                  Provide the Transport Request and execute the command “npm run deploy”.

                  You will get a message “SAP UI5 Application has been uploaded and registered successfully”.

                  4. Go to the given link and check the deployed fiori app

                  5. Now you will get the Fiori app on SAP system.

                  Deploy the Fiori app using WEBIDE

                  1. Go to the WEBIDE, right click on your project –> Select Deploy –> Choose your System (Deploy to SAPUi5 ABAP Repository)

                  2. You will be on next page (Deployment Option), Here select your required ABAP or Cloud system –> Next.

                  Note: If you are deploying first time, select Deploy a new application. Else application is already deployed, select update an existing application

                  3. Provide application Name, Description, Package, in – Deploy a New Application Screen and select Next.

                  4. If the selected package is local, Choose Finish. If it requires TR, select TR for your application.

                  A notification message displays once the application is deployed successfully.

                  5. Go to SAP Logon Pad –> Tcode SE80 –> Select BSP Application from Dropdown –> find your deployed application.

                  Steps to create a Tile and Target mapping in Fiori launchpad Designer

                  1. Create Semantic Object using TCode – /n/ui2/semobj.

                  Click on Edit Button

                  Select New Entries.

                  Provide the new Semantic Object, Object Name and Description and Click on Save Button.

                  2. Go to SAP LogOn –> Execute the TCode – /ui2/FLPD_CUST (Launchpad Designer).

                  3. Click on Setting Button –> Select the TR –> choose Ok.

                  4. If catalog information is not available, create a catalog –> Click on Plus Button –> provide the required information –> click on Save.

                  5. If catalog already exist, select the catalog –> Click on Add tile plus Button.

                  6. Select a Tile template, here I am going to select App launcher – Static.

                  7. Provide the Title, information, Semantic Object, Action and other required Information Click on Save Button.

                  8. Create a Target Mapping à Go to Target Mapping a Click on Create Target Mapping.

                  9. Provide the required information Semantic Object, Action, Title, URL, ID and Click on Save Button.

                  Note: How to get URL –> Go to the WEBIDE –> your project –> manifest.json file –> Find the URL info.

                  How to get ID: Go to the WEBIDE –> your project –> manifest.json file –> find the ID.

                  10. The Fiori app tile has been created successfully. Go to Fiori launchpadv –> App Finder –> Search your application.

                  Note: If Fiori app is not found on Fiori Launchpad à we have to assign the PFCG Role for catalog and contact security team to assign the Role.

                  Rating: 0 / 5 (0 votes)

                  The post Deploy the UI5 Fiori app on SAP ABAP repository with BAS & WEBIDE, create Fiori app Tile using Launchpad Designer appeared first on ERP Q&A.

                  ]]>