-
Notifications
You must be signed in to change notification settings - Fork 184
Open
Description
Created a Parameterized entity in AnalyticsService to test with OData V4 ALP app - travel_analytics.
Since Parameterized entity is only supported in HANA DB. Using HANA Cloud to deploy and test.
- CAP service definition for parametrized entity
// SAMPLE Parameterized entity to use with Fiori Elements OData V4 ALP
@readonly
@Capabilities.FilterRestrictions : {NonFilterableProperties: [P_Price]}
@Capabilities.NavigationRestrictions: {RestrictedProperties: [{
NavigationProperty: Parameters,
FilterRestrictions: {Filterable: false}
}]}
entity BookingsWithParam(P_Price : String(10)) as
select from my.Booking {
@UI.Hidden : false
BookingUUID as ID,
to_Travel.TravelID,
BookingID,
@title : 'Travel/Booking ID'
to_Travel.TravelID || '/' || BookingID as CombinedID : String,
ConnectionID,
FlightDate,
// pretend all bookings have the same currency so the FlightPrice can be aggregated
@title : '{i18n>CurrencyCode}'
'USD' as CurrencyCode_code : String(3),
//CurrencyCode.code as CurrencyCode_code,
@Measures.ISOCurrency: CurrencyCode_code
FlightPrice,
@title : '{i18n>BookingStatus}'
@Common.Text : statusName @Common.TextArrangement: #TextOnly
BookingStatus.code as status,
BookingStatus.name as statusName,
@Common.Text : airlineName
to_Carrier.AirlineID as airline,
to_Carrier.Name as airlineName,
BookingDate,
to_Travel,
to_Carrier,
// Java has a problem with this association
to_Flight,
// Workaround:
to_Flight.PlaneType,
to_Flight.to_Connection.Distance,
to_Flight.to_Connection.DistanceUnit,
@Common.Label: '{i18n>DepartureAirport}'
@Common.Text : DepCity
to_Flight.to_Connection.DepartureAirport.AirportID as DepAirport,
to_Flight.to_Connection.DepartureAirport.City as DepCity,
@Common.Label: '{i18n>ArrivalAirport}'
@Common.Text : DestCity
to_Flight.to_Connection.DestinationAirport.AirportID as DestAirport,
to_Flight.to_Connection.DestinationAirport.City as DestCity,
}
where
FlightPrice >= :P_Price;
- Response working using curl
{
"@odata.context": "../$metadata#BookingsWithParam(10000)/Set",
"value": [
{
"BookingDate": "2025-11-27",
"BookingID": 1,
"CombinedID": "635/1",
"ConnectionID": "0002",
"CurrencyCode_code": "USD",
"DepAirport": "SIN",
"DepCity": "Singapore",
"DestAirport": "SFO",
"DestCity": "San Francisco, California",
"Distance": 13523,
"DistanceUnit": "KM",
"FlightDate": "2025-12-11",
"FlightPrice": "10007.000",
"ID": "277E7221A8E4645C17002DF03754AB66",
"PlaneType": "747-400",
"TravelID": 635,
"airline": "SW",
"airlineName": "Sunset Wings",
"status": "N",
"statusName": "New",
"to_Carrier_AirlineID": "SW",
"to_Travel_TravelUUID": "CC677221A8E4645C17002DF03754AB66"
},
{
"BookingDate": "2025-11-27",
"BookingID": 2,
"CombinedID": "635/2",
"ConnectionID": "0002",
"CurrencyCode_code": "USD",
"DepAirport": "SIN",
"DepCity": "Singapore",
"DestAirport": "SFO",
"DestCity": "San Francisco, California",
"Distance": 13523,
"DistanceUnit": "KM",
"FlightDate": "2025-12-11",
"FlightPrice": "10007.000",
"ID": "287E7221A8E4645C17002DF03754AB66",
"PlaneType": "747-400",
"TravelID": 635,
"airline": "SW",
"airlineName": "Sunset Wings",
"status": "N",
"statusName": "New",
"to_Carrier_AirlineID": "SW",
"to_Travel_TravelUUID": "CC677221A8E4645C17002DF03754AB66"
},
{
"BookingDate": "2025-12-01",
"BookingID": 1,
"CombinedID": "636/1",
"ConnectionID": "0002",
"CurrencyCode_code": "USD",
"DepAirport": "SIN",
"DepCity": "Singapore",
"DestAirport": "SFO",
"DestCity": "San Francisco, California",
"Distance": 13523,
"DistanceUnit": "KM",
"FlightDate": "2025-12-11",
"FlightPrice": "10007.000",
"ID": "297E7221A8E4645C17002DF03754AB66",
"PlaneType": "747-400",
"TravelID": 636,
"airline": "SW",
"airlineName": "Sunset Wings",
"status": "B",
"statusName": "Accepted",
"to_Carrier_AirlineID": "SW",
"to_Travel_TravelUUID": "CD677221A8E4645C17002DF03754AB66"
}
}
- Annotations for Fiori Elements - ALP
using AnalyticsService as service from '../../srv/analytics-service';
annotate service.BookingsWithParam with @(
Aggregation.CustomAggregate #FlightPrice : 'Edm.Decimal',
Aggregation.CustomAggregate #CurrencyCode_code : 'Edm.String',
Common.SemanticKey : [ID],
) {
ID @ID : 'ID';
FlightPrice @Aggregation.default: #SUM;
CurrencyCode_code @Aggregation.default: #MAX;
};
annotate service.BookingsWithParam with @Aggregation.ApplySupported : {
Transformations : [
'aggregate',
'topcount',
'bottomcount',
'identity',
'concat',
'groupby',
'filter',
'search'
],
GroupableProperties : [
TravelID,
BookingID,
CombinedID,
ConnectionID,
FlightDate,
CurrencyCode_code,
status,
airline,
],
AggregatableProperties : [
{Property : status },
{Property : FlightPrice },
{Property : ID },
],
};
annotate service.BookingsWithParam with @(
Analytics.AggregatedProperty #countBookings :
{
Name : 'countBookings',
AggregationMethod : 'countdistinct',
AggregatableProperty : ID,
@Common.Label : '{i18n>BookingsWithParam}'
},
Analytics.AggregatedProperty #minPrice :
{
Name : 'minPrice',
AggregationMethod : 'min',
AggregatableProperty : FlightPrice,
@Common.Label : '{i18n>MinPrice}'
},
Analytics.AggregatedProperty #maxPrice :
{
Name : 'maxPrice',
AggregationMethod : 'max',
AggregatableProperty : FlightPrice,
@Common.Label : '{i18n>MaxPrice}'
},
Analytics.AggregatedProperty #avgPrice :
{
Name : 'avgPrice',
AggregationMethod : 'average',
AggregatableProperty : FlightPrice,
@Common.Label : '{i18n>AvgPrice}'
},
// measure "sum of prices" is available by default (but name/label doesn't indicate summing -> ?)
// Analytics.AggregatedProperty #sumPrice :
// {
// Name : 'sumPrice',
// AggregationMethod : 'sum',
// AggregatableProperty : FlightPrice,
// @Common.Label : '{i18n>TotalPrice}'
// }
);
annotate service.BookingsWithParam with @UI.LineItem : [
{
Value : TravelID,
@UI.Importance : #High,
@HTML5.CssDefaults: {width:'8em'},
}, {
Value : BookingID,
Label : '{i18n>Booking}',
@UI.Importance : #High,
@HTML5.CssDefaults: {width:'8em'},
}, {
Value : airline,
@UI.Importance : #High,
@HTML5.CssDefaults: {width:'14em'},
}, {
Value : ConnectionID,
@UI.Importance : #High,
@HTML5.CssDefaults: {width:'8em'},
}, {
Value : FlightDate,
@UI.Importance : #High,
}, {
Value : FlightPrice,
@UI.Importance : #High,
@HTML5.CssDefaults: {width:'12em'},
}, {
Value : status,
@UI.Importance : #High,
@HTML5.CssDefaults: {width:'8em'},
}
];
annotate service.BookingsWithParam with @UI.Chart : {
Title : '{i18n>BookingsWithParam}',
ChartType : #Column,
DynamicMeasures : [
'@Analytics.AggregatedProperty#minPrice',
'@Analytics.AggregatedProperty#maxPrice',
'@Analytics.AggregatedProperty#avgPrice'
],
Dimensions : [airline],
MeasureAttributes : [{
DynamicMeasure : '@Analytics.AggregatedProperty#minPrice',
Role : #Axis1
}],
DimensionAttributes : [{
Dimension : airline,
Role : #Category
}],
};
annotate service.BookingsWithParam with @UI.PresentationVariant : {
GroupBy : [ // default grouping in table
airline,
status
],
Total : [ // default aggregation in table
FlightPrice
],
Visualizations : [
'@UI.Chart',
'@UI.LineItem',
]
};
//
// Visual Filters
//
annotate service.BookingsWithParam with @(
UI.PresentationVariant #pvAirline : {
Visualizations : ['@UI.Chart#chartAirline']
},
UI.Chart #chartAirline : {
ChartType : #Bar,
DynamicMeasures : [
'@Analytics.AggregatedProperty#countBookings',
],
Dimensions : [airline],
MeasureAttributes : [{
DynamicMeasure : '@Analytics.AggregatedProperty#countBookings',
Role : #Axis1,
}],
DimensionAttributes : [{
Dimension : airline,
Role : #Category
}],
}
) {
airline @(
Common.ValueList #vlAirline : {
CollectionPath : 'BookingsWithParam',
PresentationVariantQualifier : 'pvAirline',
Parameters : [{
$Type : 'Common.ValueListParameterInOut',
LocalDataProperty : airline,
ValueListProperty : 'airline'
}]
},
Common.ValueList : {
CollectionPath : 'Airline',
Parameters : [{
$Type : 'Common.ValueListParameterInOut',
LocalDataProperty : airline,
ValueListProperty : 'AirlineID',
}, {
$Type : 'Common.ValueListParameterDisplayOnly',
ValueListProperty : 'Name',
}]
}
)
};
annotate service.BookingsWithParam with @(
UI.PresentationVariant #pvStatus : {
Visualizations : ['@UI.Chart#chartStatus']
},
UI.Chart #chartStatus : {
ChartType : #Bar,
DynamicMeasures : [
'@Analytics.AggregatedProperty#countBookings',
],
Dimensions : [status],
MeasureAttributes : [{
DynamicMeasure : '@Analytics.AggregatedProperty#countBookings',
Role : #Axis1,
}],
DimensionAttributes : [{
Dimension : status,
Role : #Category
}]
}
) {
status @(
Common.ValueList #vlStatus : {
CollectionPath : 'BookingsWithParam',
PresentationVariantQualifier : 'pvStatus',
Parameters : [{
$Type : 'Common.ValueListParameterInOut',
LocalDataProperty : status,
ValueListProperty : 'status'
}]
},
Common.ValueList : {
CollectionPath : 'BookingStatus',
Parameters : [{
$Type : 'Common.ValueListParameterInOut',
LocalDataProperty : status,
ValueListProperty : 'code',
}]
},
//Common.ValueListWithFixedValues : true
)
};
annotate service.BookingsWithParam with @(
UI.PresentationVariant #pvFlightDate : {
SortOrder : [{
Property : FlightDate,
Descending : true
}],
Visualizations : ['@UI.Chart#chartFlightDate']
},
UI.Chart #chartFlightDate : {
Title : 'BookingsWithParam over FlightDate',
ChartType : #Line,
DynamicMeasures : [
'@Analytics.AggregatedProperty#countBookings',
],
Dimensions : [FlightDate],
MeasureAttributes : [{
DynamicMeasure : '@Analytics.AggregatedProperty#countBookings',
Role : #Axis1,
}],
DimensionAttributes : [{
Dimension : FlightDate,
Role : #Category
}]
}
) {
FlightDate @Common.ValueList #vlFlightDate : {
CollectionPath : 'BookingsWithParam',
PresentationVariantQualifier : 'pvFlightDate',
Parameters : [{
$Type : 'Common.ValueListParameterInOut',
LocalDataProperty : FlightDate,
ValueListProperty : 'FlightDate'
}]
};
};
//
// KPI
//
annotate service.BookingsWithParam with @(
UI.KPI #myKPI1 : {
DataPoint : {
Value : FlightPrice,
Title : 'TOT',
Description : '{i18n>Total Price}',
CriticalityCalculation : {
ImprovementDirection: #Maximize,
AcceptanceRangeLowValue: 26000000,
ToleranceRangeLowValue: 24000000,
DeviationRangeLowValue: 22000000
}
},
Detail : {
DefaultPresentationVariant : {
Visualizations : [
'@UI.Chart#kpi1'
],
},
},
SelectionVariant : {
SelectOptions : [{
PropertyName : FlightPrice,
Ranges : [{
Sign : #E,
Option : #EQ,
Low : 0,
}, ],
}],
}
},
UI.Chart #kpi1 : {
ChartType : #Line,
Measures : [FlightPrice],
Dimensions : [FlightDate],
MeasureAttributes : [{
Measure : FlightPrice,
Role : #Axis1
}],
DimensionAttributes : [{
Dimension : FlightDate,
Role : #Category
}]
},
);
//
// Detail page
//
annotate service.BookingsWithParam with @UI : {
Identification : [
{ Value : CombinedID },
],
HeaderInfo : {
TypeName : '{i18n>BookingsWithParam}',
TypeNamePlural : '{i18n>BookingsWithParam}',
Title : { Value : CombinedID },
Description : { Value : CombinedID }
},
Facets : [{
$Type : 'UI.CollectionFacet',
Label : '{i18n>BookingDetails}',
ID : 'Booking',
Facets : [{
$Type : 'UI.ReferenceFacet',
ID : 'TravelData',
Target : '@UI.FieldGroup#TravelInformation',
Label : '{i18n>Travel}'
}, {
$Type : 'UI.ReferenceFacet',
ID : 'BookingData',
Target : '@UI.FieldGroup#BookingInformation',
Label : '{i18n>Booking}'
}, {
$Type : 'UI.ReferenceFacet',
ID : 'FlightData',
Target : '@UI.FieldGroup#FlightInformation',
Label : '{i18n>Flight}'
}]
}],
FieldGroup #TravelInformation : { Data : [
{ Value : to_Travel.TravelID,
Label : '{i18n>TravelID}' },
{ Value : to_Travel.Description },
{ Value : to_Travel.to_Agency.Name, },
{ Value : to_Travel.CustomerName, },
{ Value : to_Travel.TravelStatus.code,
Label : '{i18n>Status}' }, // why does the label not come from below?
]},
FieldGroup #BookingInformation : { Data : [
{ Value : BookingID,
Label : '{i18n>BookingID}' },
{ Value : BookingDate },
{ Value : FlightDate, },
{ Value : FlightPrice },
{ Value : status,
Label : '{i18n>Status}' },
]},
FieldGroup #FlightInformation : { Data : [
{ Value : airline, },
{ Value : to_Carrier.AirlinePicURL, },
{ Value : ConnectionID },
// Java doesn't work with these association paths
// { Value : to_Flight.PlaneType },
// { Value : to_Flight.to_Connection.DepartureAirport.AirportID,
// Label: '{i18n>DepartureAirport}' },
// { Value : to_Flight.to_Connection.DestinationAirport.AirportID,
// Label: '{i18n>ArrivalAirport}' },
// { Value : to_Flight.to_Connection.Distance, },
// Workaround:
{ Value : PlaneType },
{ Value : DepAirport, },
{ Value : DestAirport },
{ Value : Distance, },
]},
};
// determines the order of visual filters
annotate service.BookingsWithParam with @UI.SelectionFields : [
FlightDate,
status,
airline,
];
Error while processing building block FilterBar
TypeError: Cannot read properties of undefined (reading 'map')
at Object._formatPropertyInfo (https://ui5.sap.com/1.130.2/resources/sap/fe/templates/library-preload.js:1644:12314)
at Object.formatPropertyInfo (https://ui5.sap.com/1.130.2/resources/sap/fe/templates/library-preload.js:1644:12248)
at a.e [as getTemplate] (https://ui5.sap.com/1.130.2/resources/sap/fe/templates/library-preload.js:1679:13243)
at https://ui5.sap.com/1.130.2/resources/sap/fe/core/library-preload.js:171:10025
at i.renderAsXML (https://ui5.sap.com/1.130.2/resources/sap/fe/core/library-preload.js:61:541)
at D (https://ui5.sap.com/1.130.2/resources/sap/fe/core/library-preload.js:171:10002)
How the building block was called
<macroInternal:FilterBar xmlns:macroInternal="sap.fe.macros.internal" _applyIdToContent="true" metaPath="{entityType>}" variantBackreference="fe::PageVariantManagement" selectionFields="{filterBarContext>selectionFields}" internalFilterChanged=".handlers.onFiltersChanged" internalSearch=".handlers.onSearch" afterClear=".onAfterClear" liveMode="false" showAdaptFiltersButton="true" p13nMode="Item,Value" suspendSelection="false"/>
Trace info
{
"initialProperties": {
"showMessages": false,
"variantBackreference": "fe::PageVariantManagement",
"enableFallback": false,
"showAdaptFiltersButton": true,
"p13nMode": "Item,Value",
"useSemanticDateRange": true,
"liveMode": false,
"suspendSelection": false,
"isDraftCollaborative": false,
"initialLayout": "compact",
"showClearButton": false,
"_applyIdToContent": true,
"disableDraftEditStateFilter": false,
"useOldVH": false,
"internalFilterChanged": ".handlers.onFiltersChanged",
"internalSearch": ".handlers.onSearch",
"afterClear": ".onAfterClear"
},
"resolvedProperties": {
"contextPath": {
"path": "/BookingsWithParam/Set/",
"value": {
"$kind": "EntityType",
"$Key": [
"ID"
],
"ID": {
"$kind": "Property",
"$Type": "Edm.String",
"$Nullable": false
},
"TravelID": {
"$kind": "Property",
"$Type": "Edm.Int32",
"$DefaultValue": "0"
},
"BookingID": {
"$kind": "Property",
"$Type": "Edm.Int32"
},
"CombinedID": {
"$kind": "Property",
"$Type": "Edm.String"
},
"ConnectionID": {
"$kind": "Property",
"$Type": "Edm.String",
"$MaxLength": 4
},
"FlightDate": {
"$kind": "Property",
"$Type": "Edm.Date"
},
"CurrencyCode_code": {
"$kind": "Property",
"$Type": "Edm.String",
"$MaxLength": 3
},
"FlightPrice": {
"$kind": "Property",
"$Type": "Edm.Decimal",
"$Precision": 16,
"$Scale": 3
},
"status": {
"$kind": "Property",
"$Type": "Edm.String",
"$MaxLength": 1
},
"statusName": {
"$kind": "Property",
"$Type": "Edm.String",
"$MaxLength": 255
},
"airline": {
"$kind": "Property",
"$Type": "Edm.String",
"$MaxLength": 3
},
"airlineName": {
"$kind": "Property",
"$Type": "Edm.String",
"$MaxLength": 40
},
"BookingDate": {
"$kind": "Property",
"$Type": "Edm.Date"
},
"to_Travel": {
"$kind": "NavigationProperty",
"$Type": "AnalyticsService.Travels",
"$ReferentialConstraint": {
"to_Travel_TravelUUID": "TravelUUID"
}
},
"to_Travel_TravelUUID": {
"$kind": "Property",
"$Type": "Edm.String"
},
"to_Carrier": {
"$kind": "NavigationProperty",
"$Type": "AnalyticsService.Airline",
"$ReferentialConstraint": {
"to_Carrier_AirlineID": "AirlineID"
}
},
"to_Carrier_AirlineID": {
"$kind": "Property",
"$Type": "Edm.String",
"$MaxLength": 3
},
"to_Flight": {
"$kind": "NavigationProperty",
"$Type": "AnalyticsService.Flight",
"$ReferentialConstraint": {
"airline": "AirlineID",
"FlightDate": "FlightDate",
"ConnectionID": "ConnectionID"
}
},
"PlaneType": {
"$kind": "Property",
"$Type": "Edm.String",
"$MaxLength": 10
},
"Distance": {
"$kind": "Property",
"$Type": "Edm.Int32"
},
"DistanceUnit": {
"$kind": "Property",
"$Type": "Edm.String",
"$MaxLength": 3
},
"DepAirport": {
"$kind": "Property",
"$Type": "Edm.String",
"$MaxLength": 3
},
"DepCity": {
"$kind": "Property",
"$Type": "Edm.String",
"$MaxLength": 40
},
"DestAirport": {
"$kind": "Property",
"$Type": "Edm.String",
"$MaxLength": 3
},
"DestCity": {
"$kind": "Property",
"$Type": "Edm.String",
"$MaxLength": 40
},
"Parameters": {
"$kind": "NavigationProperty",
"$Type": "AnalyticsService.BookingsWithParamParameters",
"$Partner": "Set"
}
}
},
"isPublic": false
},
"missingContexts": {}
}Metadata
Metadata
Assignees
Labels
No labels