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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions