Skip to Content
Technical Articles

Fiori App Dynamic Comparison Table using BAS

Many a times we get requirement to prepare a dynamic table to compare attribute of an entity along a dimension which is not fixed. A common example is of comparing a commodity price or stock availability across different dates (date-range).

In this blog to keep things simple we are providing a Price Comparison for commodity based on 3 dates selected by user. This can be made a fully dynamic table as well where you can add columns as per your requirement and get the comparison.

Below is a video of what we are trying to achieve.

 

In case you are using Business Application studio, you should have Business Application Studio enabled and Fiori Dev Space created. Logic will be same even if you use Web IDE or any other tool.

Solution: 

oData Service:  An oData service is defined on backend with fixed column layout. It provides price of commodity based on the request received from frontend.

Retrieve Today’s price:

/sap/opu/odata/SAP/ZPRODUCT_COMP_SRV/ProductSet

Retrieve Today’s Price and for any other column requires passing a valid Date as filter to Date(n) properties. If date is valid, backend returns Price for that date. The following oData url will return Today’s as well price for Date1 and Date2 columns.
/sap/opu/odata/SAP/ZPRODUCT_COMP_SRV/ProductSet?$filter=Date1 eq datetime%272020-09-14T18%3a30%3a00%27 and Date2 eq datetime%272020-09-10T18%3a30%3a00%27

Sample Metadata :

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="1.0"
    xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx"
    xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
    xmlns:sap="http://www.sap.com/Protocols/SAPData">
    <edmx:DataServices m:DataServiceVersion="2.0">
        <Schema Namespace="ZPRODUCT_COMP_SRV" xml:lang="en" sap:schema-version="1"
            xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
            <EntityType Name="Product" sap:content-version="1">
                <Key>
                    <PropertyRef Name="ProductID"/>
                </Key>
                <Property Name="ProductID" Type="Edm.String" Nullable="false" MaxLength="18" sap:unicode="false" sap:label="Product"/>
                <Property Name="Productdesc" Type="Edm.String" Nullable="false" MaxLength="60" sap:unicode="false" sap:label="Product Desc"/>
                <Property Name="Today" Type="Edm.DateTime" Precision="7" sap:unicode="false" sap:label="Today"/>
                <Property Name="Date1" Type="Edm.DateTime" Precision="7" sap:unicode="false" sap:label="Date 1"/>
                <Property Name="Date2" Type="Edm.DateTime" Precision="7" sap:unicode="false" sap:label="Date 2"/>
                <Property Name="Date3" Type="Edm.DateTime" Precision="7" sap:unicode="false" sap:label="Date 3"/>
                <Property Name="Pricetoday" Type="Edm.Decimal" Precision="16" Scale="3" sap:unicode="false" sap:unit="Currency" sap:label="Net Value"/>
                <Property Name="Pricedate1" Type="Edm.Decimal" Precision="16" Scale="3" sap:unicode="false" sap:unit="Currency" sap:label="Price Date 1"/>
                <Property Name="Pricedate2" Type="Edm.Decimal" Precision="16" Scale="3" sap:unicode="false" sap:unit="Currency" sap:label="Price Date 2"/>
                <Property Name="Pricedate3" Type="Edm.Decimal" Precision="16" Scale="3" sap:unicode="false" sap:unit="Currency" sap:label="Price Date 3"/>
                <Property Name="Currency" Type="Edm.String" MaxLength="5" sap:unicode="false" sap:label="Currency" sap:semantics="currency-code"/>
            </EntityType>
            <EntityContainer Name="ZPRODUCT_COMP_SRV_Entities" m:IsDefaultEntityContainer="true" sap:supported-formats="atom json xlsx">
                <EntitySet Name="ProductSet" EntityType="ZPRODUCT_COMP_SRV.Product" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:pageable="false" sap:content-version="1"/>
            </EntityContainer>
            <atom:link rel="self" href="http://backend:8080/sap/opu/odata/sap/ZPRODUCT_COMP_SRV/$metadata"
                xmlns:atom="http://www.w3.org/2005/Atom"/>
                <atom:link rel="latest-version" href="http://backend:8080/sap/opu/odata/sap/ZPRODUCT_COMP_SRV/$metadata"
                    xmlns:atom="http://www.w3.org/2005/Atom"/>
                </Schema>
            </edmx:DataServices>
        </edmx:Edmx>

UI Development:

Open Business Application Studio and enter your Fiori Dev Space.

Select Terminal > New Terminal.

In case you are not in project directory,

user: user $ cd projects

We will use yeoman generator for project creation.

I choose to create a Fiori Project.After that it keeps asking me for further choices related to project creation. Relevant option related to your development you can keep selecting.

Here I choose SAPUI5 Application. Keep giving other details like project name etc.

When it asks to select a data service you can add here as well as choose to add later also.

Once you select yes it will ask to select a system

After selecting system select your source.And then select your oData service from the list. We are done with our project creation.

Open your workspace.

Expand your HTML5Module.Here you will find webapp folder.

Goto View ProductsListView

 

Replace the code there with below xml code.

<mvc:View
	controllerName="pp.PriceComparisonTool.controller.ProductsList"
	xmlns:mvc="sap.ui.core.mvc"
	xmlns:core="sap.ui.core"
    xmlns:uxap="sap.uxap"
	xmlns="sap.m">
<uxap:ObjectPageLayout id="ObjectPageLayout" preserveHeaderStateOnScroll="true">
<uxap:headerTitle>
<uxap:ObjectPageDynamicHeaderTitle>
		<uxap:heading>
					<Title text="Products Price Comparison" />
				</uxap:heading>
</uxap:ObjectPageDynamicHeaderTitle>
</uxap:headerTitle>
<uxap:sections>
<uxap:ObjectPageSection titleUppercase="false" title="Details">
<uxap:subSections>
<uxap:ObjectPageSubSection titleUppercase="false">
	<uxap:blocks>
    <Table id="idProductsTable"
		inset="false"
		items="{
			path: '/ProductSet'
		}">
		<infoToolbar>
			<OverflowToolbar>
				<Label text="You can compare price for selected dates"/>
			</OverflowToolbar>
		</infoToolbar>
		<columns>
			<Column
				width="12em">
				<Text text="Product" />
			</Column>
			<Column
				minScreenWidth="Tablet"
				demandPopin="true">
				<Text text="Todays Price" />
			</Column>
			<Column
				minScreenWidth="Desktop"
				demandPopin="true"
				hAlign="End">
						<DatePicker
			id="DP1"
			placeholder="Enter Date ..."
			change="handleChange"
			class="sapUiSmallMarginBottom"/>
			</Column>
			<Column
				minScreenWidth="Desktop"
				demandPopin="true"
				hAlign="End">
						<DatePicker
			id="DP2"
			placeholder="Enter Date ..."
			change="handleChange"
			class="sapUiSmallMarginBottom"/>
			</Column>
			<Column
				minScreenWidth="Desktop"
				demandPopin="true"
				hAlign="End">
						<DatePicker
			id="DP3"
			placeholder="Enter Date ..."
			change="handleChange"
			class="sapUiSmallMarginBottom"/>
			</Column>
		</columns>
		<items>
			<ColumnListItem>
				<cells>
					<ObjectIdentifier
						title="{ProductID}"
						text="{Productdesc}"/>
					<Text
						text="{Pricetoday}" />
					<Text 
						text="{Pricedate1}" />
					<Text
						text="{Pricedate2}" />
				<Text
						text="{Pricedate3}" />
				</cells>
			</ColumnListItem>
		</items>
	</Table>
    	</uxap:blocks>
</uxap:ObjectPageSubSection>
</uxap:subSections>
</uxap:ObjectPageSection>
</uxap:sections>
</uxap:ObjectPageLayout>
</mvc:View>

 

Then go to ProductsList.controller.js. There I added the method handleChange.

sap.ui.define([
		"sap/ui/core/mvc/Controller"
	],
	/**
     * @param {typeof sap.ui.core.mvc.Controller} Controller
     */
	function (Controller) {
		"use strict";

		return Controller.extend("pp.PriceComparisonTool.controller.ProductsList", {
			onInit: function () {

            },
                        handleChange: function (oEvent) {
                var oDate1 = this.getView().byId("DP1").getDateValue();
                var oDate2 = this.getView().byId("DP2").getDateValue();
                var oDate3 = this.getView().byId("DP3").getDateValue();
                var filters = [];
                if (oDate1 && oDate1 != null) {
                    var oFilter1 = new sap.ui.model.Filter("Date1", sap.ui.model.FilterOperator.EQ, oDate1);
                    filters.push(oFilter1);
                }
                
                if (oDate2 && oDate2 != null) {
                    var oFilter2 = new sap.ui.model.Filter("Date2", sap.ui.model.FilterOperator.EQ, oDate2);
                    filters.push(oFilter2);
                }
                
                if (oDate3 && oDate3 != null) {
                    var oFilter3 = new sap.ui.model.Filter("Date3", sap.ui.model.FilterOperator.EQ, oDate3);
                    filters.push(oFilter3);
                }
                var olist = this.getView().byId("idProductsTable");
                var binding = olist.getBinding("items");
                binding.filter(filters);
            }
		});
	});

 

This way we can achieve this.More complex scenarios can be built on top of this.

Be the first to leave a comment
You must be Logged on to comment or reply to a post.