Skip to content

Converted Bookings in AnalyticsService to a parameterized entity but travel_analytics app not able to use it #1502

@dracovoldy

Description

@dracovoldy

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

GET https://port4004-workspaces-ws-xxxxx.xxxx.applicationstudio.cloud.sap/analytics/BookingsWithParamParameters(P_Price=10000)/Set

{
"@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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions