**TITLE**: Custom Header

**INTRODUCTION**: No introduction

**TAGS**: custom header, list report, header customization, extensions

**STEP**: Configuring Fragment Settings in the Manifest

**DESCRIPTION**: You can specify separate fragments in the manifest.json file for the expanded header and the collapsed header, as shown in the following sample code:

**LANGUAGE**: JSON

**CODE**:
```json
{
	"_version": "1.12.0",
	"sap.app": {
		"id": "sap.fe.core.fpmExplorer.customHeaderListReport",
		"type": "application",
		"i18n": {
			"bundleUrl": "i18n/i18n.properties",
			"supportedLocales": [""],
			"fallbackLocale": ""
		},
		"applicationVersion": {
			"version": "1.0.0"
		},
		"dataSources": {
			"mainService": {
				"uri": "/sap/fe/core/mock/service/",
				"type": "OData",
				"settings": {
					"annotations": [],
					"odataVersion": "4.0"
				}
			}
		}
	},
	"sap.ui5": {
		"dependencies": {
			"minUI5Version": "1.111.1",
			"libs": {
				"sap.ui.core": {},
				"sap.fe.templates": {}
			}
		},
		"contentDensities": {
			"compact": true,
			"cozy": true
		},
		"models": {
			"": {
				"dataSource": "mainService",
				"settings": {
					"operationMode": "Server",
					"autoExpandSelect": true,
					"earlyRequests": true
				}
			}
		},
		"extends": {
			"extensions": {
				"sap.ui.controllerExtensions": {
					"sap.fe.templates.ListReport.ListReportController": {
						"controllerName": "sap.fe.core.fpmExplorer.customHeaderListReport.LRExtend"
					}
				}
			}
		},
		"rootView": {
			"viewName": "sap.fe.core.fpmExplorer.customHeaderListReport.CustomHeaderListReport"
		},
		"routing": {
			"routes": [
				{
					"pattern": ":?query:",
					"name": "listPage",
					"target": "listPage"
				},
				{
					"pattern": "/Travel({key}):?query:",
					"name": "objectPage",
					"target": "objectPage"
				}
			],
			"targets": {
				"listPage": {
					"type": "Component",
					"id": "Default",
					"name": "sap.fe.templates.ListReport",
					"options": {
						"settings": {
							"contextPath": "/Travel",
							"variantManagement": "Page",
							"initialLoad": "Enabled",
							"liveMode": true,
							"controlConfiguration": {
								"@com.sap.vocabularies.UI.v1.LineItem": {
									"tableSettings": {
										"beforeRebindTable": ".extension.sap.fe.core.fpmExplorer.customHeaderListReport.LRExtend.beforeRebindTableLR"
									}
								}
							},
							"content": {
								"header": {
									"customHeader": {
										"expandedHeaderFragment": "sap.fe.core.fpmExplorer.customHeaderListReport.CustomHeaderExpanded",
										"collapsedHeaderFragment": "sap.fe.core.fpmExplorer.customHeaderListReport.CustomHeaderCollapsed"
									}
								}
							},
							"navigation": {
								"Travel": {
									"detail": {
										"route": "objectPage"
									}
								}
							}
						}
					}
				},
				"objectPage": {
					"type": "Component",
					"id": "objectPage",
					"name": "sap.fe.templates.ObjectPage",
					"options": {
						"settings": {
							"contextPath": "/Travel"
						}
					}
				}
			}
		}
	}
}
```

**STEP**: Defining the Fragment for the Expanded Header

**DESCRIPTION**: Use the GenericTile control with its properties and press handlers to display tiles in the header of the list report page.

**LANGUAGE**: XML

**CODE**:
```xml
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:macros="sap.fe.macros" xmlns:f="sap.f">
	<HBox>
		<GenericTile
			class="sapUiTinyMarginBegin"
			header="All Travel entities"
			subheader="No filtering"
			press=".extension.sap.fe.core.fpmExplorer.customHeaderListReport.LRExtend.pressTravelEntitiesNoFilter"
			id="tileId"
		>
			<TileContent unit="Travels">
				<NumericContent id="numericId" withMargin="false" />
			</TileContent>
		</GenericTile>
		<GenericTile
			class="sapUiTinyMarginBegin"
			header="Open Travel entities"
			subheader="Status Open"
			press=".extension.sap.fe.core.fpmExplorer.customHeaderListReport.LRExtend.pressTravelEntitiesWithFilter"
		>
			<TileContent unit="Travels">
				<NumericContent value="2" withMargin="false" />
			</TileContent>
		</GenericTile>
		<GenericTile
			class="sapUiTinyMarginBegin"
			header="Other Actions..."
			subheader="...to be executed"
			press=".extension.sap.fe.core.fpmExplorer.customHeaderListReport.LRExtend.pressNavigation"
		>
			<TileContent unit="Travels">
				<NumericContent value="x" withMargin="false" />
			</TileContent>
		</GenericTile>
	</HBox>
</core:FragmentDefinition>
```

**STEP**: Defining the Fragment for the Collapsed Header

**DESCRIPTION**: Use the KPITag building block to display KPI tags in the collapsed header.

**LANGUAGE**: XML

**CODE**:
```xml
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:mc="sap.suite.ui.microchart" xmlns:macros="sap.fe.macros">
	<HBox>
		<HBox class="sapUiTinyMarginEnd">
			<FlexBox alignItems="Center" justifyContent="Start" class="sapUiTinyMarginEnd">
				<Label text="No filtering" class="sapUiSmallMarginEnd" />
				<macros:KPITag
					id="TravelEntitiesNoFilter"
					number="4"
					status="Success"
					unit="Travels"
					press=".extension.sap.fe.core.fpmExplorer.customHeaderListReport.LRExtend.pressTravelEntitiesNoFilter"
				/>
			</FlexBox>
		</HBox>
		<HBox class="sapUiTinyMarginEnd">
			<FlexBox alignItems="Center" justifyContent="Start" class="sapUiTinyMarginEnd">
				<Label text="Status Open" class="sapUiSmallMarginEnd" />
				<macros:KPITag
					id="TravelEntitiesWithFilter"
					number="2"
					status="Information"
					unit="Travels"
					press=".extension.sap.fe.core.fpmExplorer.customHeaderListReport.LRExtend.pressTravelEntitiesWithFilter"
				/>
			</FlexBox>
		</HBox>
		<HBox class="sapUiTinyMarginEnd">
			<FlexBox alignItems="Center" justifyContent="Start" class="sapUiTinyMarginEnd">
				<Label text="Other Actions..." class="sapUiSmallMarginEnd" />
				<macros:KPITag
					id="Navigation"
					number="x"
					status="Information"
					unit="Travels"
					press=".extension.sap.fe.core.fpmExplorer.customHeaderListReport.LRExtend.pressNavigation"
				/>
			</FlexBox>
		</HBox>
	</HBox>
</core:FragmentDefinition>
```

**STEP**: Configuring Extension Settings in the Manifest

**DESCRIPTION**: You define the controller for the extension in the extensions section of the manifest.json file.

**LANGUAGE**: JSON

**CODE**:
```json
{
	"_version": "1.12.0",
	"sap.app": {
		"id": "sap.fe.core.fpmExplorer.customHeaderListReport",
		"type": "application",
		"i18n": {
			"bundleUrl": "i18n/i18n.properties",
			"supportedLocales": [""],
			"fallbackLocale": ""
		},
		"applicationVersion": {
			"version": "1.0.0"
		},
		"dataSources": {
			"mainService": {
				"uri": "/sap/fe/core/mock/service/",
				"type": "OData",
				"settings": {
					"annotations": [],
					"odataVersion": "4.0"
				}
			}
		}
	},
	"sap.ui5": {
		"dependencies": {
			"minUI5Version": "1.111.1",
			"libs": {
				"sap.ui.core": {},
				"sap.fe.templates": {}
			}
		},
		"contentDensities": {
			"compact": true,
			"cozy": true
		},
		"models": {
			"": {
				"dataSource": "mainService",
				"settings": {
					"operationMode": "Server",
					"autoExpandSelect": true,
					"earlyRequests": true
				}
			}
		},
		"extends": {
			"extensions": {
				"sap.ui.controllerExtensions": {
					"sap.fe.templates.ListReport.ListReportController": {
						"controllerName": "sap.fe.core.fpmExplorer.customHeaderListReport.LRExtend"
					}
				}
			}
		},
		"rootView": {
			"viewName": "sap.fe.core.fpmExplorer.customHeaderListReport.CustomHeaderListReport"
		},
		"routing": {
			"routes": [
				{
					"pattern": ":?query:",
					"name": "listPage",
					"target": "listPage"
				},
				{
					"pattern": "/Travel({key}):?query:",
					"name": "objectPage",
					"target": "objectPage"
				}
			],
			"targets": {
				"listPage": {
					"type": "Component",
					"id": "Default",
					"name": "sap.fe.templates.ListReport",
					"options": {
						"settings": {
							"contextPath": "/Travel",
							"variantManagement": "Page",
							"initialLoad": "Enabled",
							"liveMode": true,
							"controlConfiguration": {
								"@com.sap.vocabularies.UI.v1.LineItem": {
									"tableSettings": {
										"beforeRebindTable": ".extension.sap.fe.core.fpmExplorer.customHeaderListReport.LRExtend.beforeRebindTableLR"
									}
								}
							},
							"content": {
								"header": {
									"customHeader": {
										"expandedHeaderFragment": "sap.fe.core.fpmExplorer.customHeaderListReport.CustomHeaderExpanded",
										"collapsedHeaderFragment": "sap.fe.core.fpmExplorer.customHeaderListReport.CustomHeaderCollapsed"
									}
								}
							},
							"navigation": {
								"Travel": {
									"detail": {
										"route": "objectPage"
									}
								}
							}
						}
					}
				},
				"objectPage": {
					"type": "Component",
					"id": "objectPage",
					"name": "sap.fe.templates.ObjectPage",
					"options": {
						"settings": {
							"contextPath": "/Travel"
						}
					}
				}
			}
		}
	}
}
```

**STEP**: Implementing the Controller

**DESCRIPTION**: You use the Controller implementation to set the filtering and to handle the press event for the action to be triggered.

**LANGUAGE**: TypeScript

**CODE**:
```typescript
import BaseControllerExtension from "sap/fe/core/controllerextensions/BaseControllerExtension";
import type CollectionBindingInfoAPI from "sap/fe/macros/CollectionBindingInfo";
import type Table from "sap/fe/macros/Table";
import type ListReportController from "sap/fe/templates/ListReport/ListReportController.controller";
import MessageToast from "sap/m/MessageToast";
import type NumericContent from "sap/m/NumericContent";
import type UI5Event from "sap/ui/base/Event";

/**
 * Controller extension for custom List Report functionality.
 * @namespace sap.fe.core.fpmExplorer.customHeaderListReport
 */
export default class LRExtend extends BaseControllerExtension<ListReportController> {
	/**
	 * Handles navigation press events.
	 * @param event The UI5 event
	 */
	public pressNavigation(event: UI5Event): void {
		MessageToast.show("Any other action to be executed on pressing the tile");
	}

	/**
	 * Handles travel entities press without filter.
	 * @param event The UI5 event
	 */
	public pressTravelEntitiesNoFilter(event: UI5Event): void {
		const filters = this.base.getExtensionAPI().getFilters()?.filters as any;
		const tFilters = filters[0].aFilters ?? filters;

		for (const filter of tFilters) {
			this.base.getExtensionAPI().setFilterValues(filter.sPath, "EQ");
		}
	}

	/**
	 * Handles travel entities press with filter.
	 * @param event The UI5 event
	 */
	public pressTravelEntitiesWithFilter(event: UI5Event): void {
		this.base.getExtensionAPI().setFilterValues("TravelStatus_code", "EQ", "O");
	}

	/**
	 * Handles before rebind table event for List Report.
	 * @param event The UI5 event with collection binding info
	 */
	public beforeRebindTableLR(event: UI5Event<{ collectionBindingInfo: CollectionBindingInfoAPI }, Table>): void {
		const collectionBindingInfoAPI = event.getParameter("collectionBindingInfo");
		collectionBindingInfoAPI.attachEvent(
			"dataReceived",
			() => {
				const tableCount = (
					this.base
						.getExtensionAPI()
						.byId("sap.fe.core.fpmExplorer.customHeaderListReport::listPage--fe::table::Travel::LineItem::Table") as Table
				)
					.getCount()
					?.toString();
				(
					this.base
						.getExtensionAPI()
						.byId("sap.fe.core.fpmExplorer.customHeaderListReport::listPage--numericId") as NumericContent
				).setValue(tableCount);
			},
			this
		);
	}
}
```

**ADDITIONAL RELATED CODE BLOCKS**:

**FILE**: service.cds

**LANGUAGE**: CDS

**CODE**:
```cds
using {
  sap,
  managed,
  Currency,
  Country
} from '@sap/cds/common';

using from '../service/annotations';

@cds.autoexpose  @readonly
aspect MasterData {}

service TravelService {
  @odata.draft.enabled
  @Common.SemanticKey: [TravelID]

  entity Travel : managed {
    key TravelUUID    : UUID;

        @Common.Label          : 'ID'
        @Common.Text           : Description
        TravelID      : Integer default 0                         @readonly;

        @Common.Label          : 'Begin Date'
        BeginDate     : Date;

        @Common.Label          : 'End Date'
        EndDate       : Date;

        @Common.Label          : 'Booking Fee'
        BookingFee    : Decimal(10, 2) default 0                  @Measures.ISOCurrency: CurrencyCode_code;

        @Common.Label          : 'Total Price'
        TotalPrice    : Decimal(10, 2)                            @readonly  @Measures.ISOCurrency: CurrencyCode_code;

        @Common.Label          : 'Currency'
        CurrencyCode  : Association to CurrencyCode default 'EUR' @mandatory;

        @Common.Label          : 'Description'
        Description   : String(1024);

        @Common.Label          : 'Travel Details'
        @UI.MultiLineText
        TravelDetails : String(1024);

        @title                 : 'Status'
        @Common.Text           : TravelStatus.name
        @Common.TextArrangement: #TextOnly
        TravelStatus  : Association to TravelStatus default 'O'   @readonly;

        @title                 : 'Agency'
        @Common.Text           : to_Agency.Name
        @Common.TextArrangement: #TextFirst
        to_Agency     : Association to TravelAgency               @mandatory;

        to_Booking    : Composition of many Booking
                          on to_Booking.to_Travel = $self;
  };

  entity Booking : managed {
    key BookingUUID   : UUID;

        @Common.Label: 'Booking ID'
        BookingID     : Integer                                  @Core.Computed;

        @Common.Label: 'Booking Date'
        BookingDate   : Date;

        @Common.Label: 'Connection'
        ConnectionID  : String(4)                                @mandatory;

        @Common.Label: 'Flight Date'
        FlightDate    : Date                                     @mandatory;

        @Common.Label: 'Flight Price'
        FlightPrice   : Decimal(10, 2)                           @Measures.ISOCurrency: CurrencyCode_code;

        @Common.Label: 'Currency'
        CurrencyCode  : Currency default 'EUR'                   @mandatory;

        @Common.Label: 'Status'
        BookingStatus : Association to BookingStatus default 'N' @mandatory;
        to_Travel     : Association to Travel                    @mandatory;

        PaymentMethod : String(1) default 'B'                    @Common              : {
          Label                   : 'Payment Method',
          Text                    : _Payment.Method,
          TextArrangement         : #TextOnly,
          ValueListWithFixedValues: true,
          ValueList               : {
            Label         : 'Payment Method',
            CollectionPath: 'Payment',
            Parameters    : [{
              $Type            : 'Common.ValueListParameterInOut',
              LocalDataProperty: PaymentMethod,
              ValueListProperty: 'code'
            }]
          }
        };
        _Payment      : Association to one Payment
                          on _Payment.code = PaymentMethod;
  };

  entity Payment {
    key code   : String(1) @(Common: {
          Label          : 'Payment Code',
          Text           : Method,
          TextArrangement: #TextFirst
        });
        Method : String    @(
          Core.Immutable: true,
          Common.Label  : 'Payment Method'
        );
  }

  entity TravelStatus : sap.common.CodeList {
    key code        : String(1) @Common.Text: descr;
        name        : String(255);
        descr       : String(1000);
        criticality : Int16     @odata.Type : 'Edm.Byte' enum {
          Neutral  = 0;
          Negative = 1;
          Critical = 2;
          Positive = 3;
          NewItem  = 5
        };
  };

  entity CurrencyCode : sap.common.CodeList {
        @Common.Label: 'Currency Code'
    key code  : String(3);

        @Common.Label: 'Currency Description'
        descr : String(255);
  };

  entity BookingStatus : sap.common.CodeList {
    key code : BookingStatusCode
  };

  entity TravelAgency : MasterData {
        @Common.Label: 'Agency ID'
        @Common.Text : Name
    key AgencyID       : String(6);

        @Common.Label: 'Agency Name'
        Name           : String(80);
        Street         : String(60);

        @Common.Label: 'Postal Code'
        PostalCode     : String(10);

        @Common.Label: 'City'
        City           : String(40);

        @Common.Label: 'Country Code'
        CountryCode    : Country;

        @Common.Label: 'Phone Number'
        PhoneNumber    : String(30);

        @Common.Label: 'Email Address'
        EMailAddress   : String(256);

        @Common.Label: 'Web Address'
        WebAddress     : String(256);
        Rating         : Integer;
        Recommendation : Integer;
  };

  type TravelStatusCode  : String(1) enum {
    Open     = 'O';
    Accepted = 'A';
    Canceled = 'X';
  };

  type BookingStatusCode : String(1) enum {
    New      = 'N';
    Booked   = 'B';
    Canceled = 'X';
  };
}

```

**FILE**: annotations.cds

**LANGUAGE**: CDS

**CODE**:
```cds
using TravelService as service from '../service/service';

annotate service.Travel {
  TravelStatus @Common.ValueListWithFixedValues;
  CurrencyCode @Common.ValueList: {
    CollectionPath: 'Currencies',
    Parameters    : [
      {
        $Type            : 'Common.ValueListParameterInOut',
        LocalDataProperty: CurrencyCode_code,
        ValueListProperty: 'code'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'name'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'descr'
      }
    ]
  };
}

annotate service.Travel with @UI.LineItem: [
  {Value: TravelID},
  {
    $Type : 'UI.DataFieldForAnnotation',
    Target: '@UI.ConnectedFields#TripDates'
  },
  {Value: to_Agency_AgencyID},
  {
    Value             : TravelStatus_code,
    Criticality       : TravelStatus.criticality,
    @UI.Importance    : #High,
    @HTML5.CssDefaults: {width: '10em'}
  },
  {Value: BookingFee},
  {Value: TotalPrice}
];

annotate service.Travel with @(UI: {SelectionFields: [
  TravelID,
  to_Agency_AgencyID,
  TravelStatus_code,
  BeginDate,
  EndDate
]});

annotate service.Travel with @Capabilities.FilterRestrictions.FilterExpressionRestrictions: [
  {
    Property          : 'BeginDate',
    AllowedExpressions: 'SingleRange'
  },
  {
    Property          : 'EndDate',
    AllowedExpressions: 'SingleRange'
  }
];

annotate service.Travel with @(UI: {
  FieldGroup #TravelData    : {Data: [
    {Value: TravelID},
    {Value: to_Agency_AgencyID},
    {Value: BeginDate},
    {Value: EndDate}
  ]},
  FieldGroup #ApprovalData  : {Data: [
    {
      $Type      : 'UI.DataField',
      Value      : TravelStatus_code,
      Criticality: TravelStatus.criticality,
      Label      : 'Status'
    },
    {Value: BookingFee},
    {Value: TotalPrice}
  ]},
  FieldGroup #HeaderMain    : {Data: [
    {Value: BeginDate},
    {Value: EndDate},
    {Value: TotalPrice}
  ]},
  ConnectedFields #TripDates: {
    Label   : 'Business Trip Dates',
    Template: '{BeginDate} / {EndDate}',
    Data    : {
      BeginDate: {
        $Type: 'UI.DataField',
        Value: BeginDate
      },
      EndDate  : {
        $Type: 'UI.DataField',
        Value: EndDate
      }
    }
  },
  Facets                    : [
    {
      $Type : 'UI.ReferenceFacet',
      ID    : 'TravelData',
      Label : 'Travel Information',
      Target: '@UI.FieldGroup#TravelData',
    },
    {
      $Type : 'UI.ReferenceFacet',
      ID    : 'ApprovalData',
      Label : 'Approval Data',
      Target: '@UI.FieldGroup#ApprovalData'
    },
    {
      $Type : 'UI.ReferenceFacet',
      ID    : 'BookingList',
      Label : 'Bookings',
      Target: 'to_Booking/@UI.LineItem'
    }
  ],
  HeaderFacets              : [{
    $Type : 'UI.ReferenceFacet',
    Target: '@UI.FieldGroup#HeaderMain'
  }],
  HeaderInfo                : {
    TypeName      : 'Travel',
    TypeNamePlural: 'Travels',
    Title         : {
      $Type: 'UI.DataField',
      Value: Description
    },
    Description   : {
      $Type: 'UI.DataField',
      Value: TravelID
    },
    TypeImageUrl  : 'sap-icon://header',
  }
});

annotate service.Travel {
  to_Agency @Common.ValueList: {
    CollectionPath: 'TravelAgency',
    Label         : '',
    Parameters    : [
      {
        $Type            : 'Common.ValueListParameterInOut',
        LocalDataProperty: to_Agency_AgencyID,
        ValueListProperty: 'AgencyID'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'Name'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'Street'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'PostalCode'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'City'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'CountryCode_code'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'PhoneNumber'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'EMailAddress'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'WebAddress'
      }
    ]
  };
}

annotate service.TravelAgency with @(UI: {
  DataPoint #Recommendation: {
    Value        : Recommendation,
    TargetValue  : 100.0,
    Title        : 'Recommendation',
    Visualization: #Progress
  },
  DataPoint #Rating        : {
    Value        : Rating,
    TargetValue  : 5.0,
    Title        : 'Rating',
    Visualization: #Rating
  },
  FieldGroup #Contact      : {Data: [{
    $Type : 'UI.DataFieldForAnnotation',
    Target: '@Communication.Contact',
    Label : 'Travel Agency'
  }]}
});

annotate service.TravelAgency with @(
  Communication.Contact : {
    email: [{
      type   : #work,
      address: EMailAddress
    }],
    fn   : Name,
    adr  : [{
      type    : #work,
      code    : PostalCode,
      country : CountryCode_code,
      locality: City
    }]
  },
  Common.IsNaturalPerson: false
);

annotate service.Booking {
  CurrencyCode @Common.ValueList: {
    CollectionPath: 'Currencies',
    Parameters    : [
      {
        $Type            : 'Common.ValueListParameterInOut',
        LocalDataProperty: CurrencyCode_code,
        ValueListProperty: 'code'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'name'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'descr'
      }
    ]
  };
}

annotate service.Booking with @(UI: {
  HeaderInfo: {
    TypeName      : 'Booking',
    TypeNamePlural: 'Bookings',
    TypeImageUrl  : 'sap-icon://alert',
    Title         : {
      $Type: 'UI.DataField',
      Value: BookingID
    }
  },
  Facets    : [{
    $Type : 'UI.ReferenceFacet',
    ID    : 'FacetIdentifier1',
    Target: '@UI.FieldGroup'
  }],
  LineItem  : [
    {Value: BookingID},
    {Value: BookingDate},
    {Value: ConnectionID},
    {Value: FlightDate},
    {Value: FlightPrice}
  ],
  FieldGroup: {Data: [
    {
      $Type: 'UI.DataField',
      Value: BookingID
    },
    {
      $Type: 'UI.DataField',
      Value: BookingDate
    },
    {
      $Type: 'UI.DataField',
      Value: FlightDate
    },
    {
      $Type: 'UI.DataField',
      Value: FlightPrice
    }
  ]}
});

annotate service.TravelAgency with @(UI: {FieldGroup #Link: {Data: [{
  $Type: 'UI.DataFieldWithUrl',
  Value: Name,
  Url  : WebAddress
}]}});

```

**FILE**: Travel.json

**LANGUAGE**: JSON

**CODE**:
```json
[
	{
		"TravelUUID": "52657221A8E4645C17002DF03754AB66",
		"TravelID": "00000001",
		"BeginDate": "2025-11-04",
		"EndDate": "2025-11-06",
		"BookingFee": "20.00",
		"TotalPrice": "900.00",
		"CurrencyCode_code": "USD",
		"Description": "Business Trip for Christine, Pierre",
		"TravelDetails": "This business trip includes a two-day customer workshop at the airport. The goal is the evaluation of the customer's use cases and the alignment on the road map for the upcoming year.",
		"TravelStatus_code": "A",
		"to_Agency_AgencyID": "070001"
	},
	{
		"TravelUUID": "53657221A8E4645C17002DF03754AB66",
		"TravelID": "00000002",
		"BeginDate": "2025-12-04",
		"EndDate": "2025-12-16",
		"BookingFee": "80.00",
		"TotalPrice": "3164.00",
		"CurrencyCode_code": "USD",
		"Description": "Lars Jensen site visit for system rollout support",
		"TravelDetails": "Will be provided soon...",
		"TravelStatus_code": "O",
		"to_Agency_AgencyID": "070002"
	},
	{
		"TravelUUID": "54657221A8E4645C17002DF03754AB66",
		"TravelID": "00000003",
		"BeginDate": "2025-08-04",
		"EndDate": "2025-08-08",
		"BookingFee": "40.00",
		"TotalPrice": "1871.00",
		"CurrencyCode_code": "USD",
		"Description": "John Smith customer workshop at Acme Corp headquarters",
		"TravelDetails": "Will be provided soon...",
		"TravelStatus_code": "O",
		"to_Agency_AgencyID": "070003"
	},
	{
		"TravelUUID": "55657221A8E4645C17002DF03754AB66",
		"TravelID": "00000004",
		"BeginDate": "2025-09-04",
		"EndDate": "2025-09-05",
		"BookingFee": "40.00",
		"TotalPrice": "1240.00",
		"CurrencyCode_code": "USD",
		"Description": "Anna Müller onboarding with new project team in Berlin",
		"TravelDetails": "Will be provided soon...",
		"TravelStatus_code": "X",
		"to_Agency_AgencyID": "070003"
	}
]

```

**FILE**: Booking.json

**LANGUAGE**: JSON

**CODE**:
```json
[
	{
		"BookingUUID": "1A757221A8E4645C17002DF03754AB66",
		"to_Travel_TravelUUID": "52657221A8E4645C17002DF03754AB66",
		"BookingID": "0001",
		"BookingDate": "2025-10-20",
		"ConnectionID": "1001",
		"FlightDate": "2025-11-04",
		"FlightPrice": "405.00",
		"CurrencyCode_code": "USD",
		"BookingStatus_code": "N",
		"PaymentMethod": "B"
	},
	{
		"BookingUUID": "1B757221A8E4645C17002DF03754AB66",
		"to_Travel_TravelUUID": "52657221A8E4645C17002DF03754AB66",
		"BookingID": "0002",
		"BookingDate": "2025-10-20",
		"ConnectionID": "1002",
		"FlightDate": "2025-11-06",
		"FlightPrice": "495.00",
		"CurrencyCode_code": "USD",
		"BookingStatus_code": "N",
		"PaymentMethod": "B"
	},
	{
		"BookingUUID": "2A757221A8E4645C17002DF03754AB66",
		"to_Travel_TravelUUID": "53657221A8E4645C17002DF03754AB66",
		"BookingID": "0001",
		"BookingDate": "2025-11-20",
		"ConnectionID": "2001",
		"FlightDate": "2025-12-04",
		"FlightPrice": "1492.08",
		"CurrencyCode_code": "USD",
		"BookingStatus_code": "N",
		"PaymentMethod": "B"
	},
	{
		"BookingUUID": "2B757221A8E4645C17002DF03754AB66",
		"to_Travel_TravelUUID": "53657221A8E4645C17002DF03754AB66",
		"BookingID": "0002",
		"BookingDate": "2025-11-20",
		"ConnectionID": "2002",
		"FlightDate": "2025-12-16",
		"FlightPrice": "1671.92",
		"CurrencyCode_code": "USD",
		"BookingStatus_code": "N",
		"PaymentMethod": "B"
	},
	{
		"BookingUUID": "3A757221A8E4645C17002DF03754AB66",
		"to_Travel_TravelUUID": "54657221A8E4645C17002DF03754AB66",
		"BookingID": "0001",
		"BookingDate": "2025-07-20",
		"ConnectionID": "3001",
		"FlightDate": "2025-08-04",
		"FlightPrice": "785.82",
		"CurrencyCode_code": "USD",
		"BookingStatus_code": "N",
		"PaymentMethod": "B"
	},
	{
		"BookingUUID": "3B757221A8E4645C17002DF03754AB66",
		"to_Travel_TravelUUID": "54657221A8E4645C17002DF03754AB66",
		"BookingID": "0002",
		"BookingDate": "2025-07-20",
		"ConnectionID": "3002",
		"FlightDate": "2025-08-08",
		"FlightPrice": "1085.18",
		"CurrencyCode_code": "USD",
		"BookingStatus_code": "N",
		"PaymentMethod": "B"
	},
	{
		"BookingUUID": "4A757221A8E4645C17002DF03754AB66",
		"to_Travel_TravelUUID": "55657221A8E4645C17002DF03754AB66",
		"BookingID": "0001",
		"BookingDate": "2025-08-20",
		"ConnectionID": "4001",
		"FlightDate": "2025-09-04",
		"FlightPrice": "632.40",
		"CurrencyCode_code": "USD",
		"BookingStatus_code": "N",
		"PaymentMethod": "B"
	},
	{
		"BookingUUID": "4B757221A8E4645C17002DF03754AB66",
		"to_Travel_TravelUUID": "55657221A8E4645C17002DF03754AB66",
		"BookingID": "0002",
		"BookingDate": "2025-08-20",
		"ConnectionID": "4002",
		"FlightDate": "2025-09-05",
		"FlightPrice": "607.60",
		"CurrencyCode_code": "USD",
		"BookingStatus_code": "N",
		"PaymentMethod": "B"
	}
]

```

Custom Header

custom header
list report
header customization
extensions


**TITLE**: Custom KPI Tag

**INTRODUCTION**: No introduction

**TAGS**: custom KPI, KPI tags, list report, metrics, performance indicators

**STEP**: Defining the KPI Tag in the Manifest

**DESCRIPTION**: Define your custom KPI tags in the manifest.json file under the keyPerformanceIndicators section. Each KPI references a fragment template that defines its appearance and behavior.

**LANGUAGE**: JSON

**CODE**:
```json
{
	"_version": "1.12.0",
	"sap.app": {
		"id": "sap.fe.core.fpmExplorer.customKPI",
		"type": "application",
		"applicationVersion": {
			"version": "1.0.0"
		},
		"dataSources": {
			"mainService": {
				"uri": "/sap/fe/core/mock/service/",
				"type": "OData",
				"settings": {
					"annotations": [],
					"odataVersion": "4.0"
				}
			}
		}
	},
	"sap.ui5": {
		"dependencies": {
			"minUI5Version": "1.111.1",
			"libs": {
				"sap.ui.core": {},
				"sap.fe.templates": {}
			}
		},
		"contentDensities": {
			"compact": true,
			"cozy": true
		},
		"models": {
			"": {
				"dataSource": "mainService",
				"settings": {
					"operationMode": "Server",
					"autoExpandSelect": true,
					"earlyRequests": true
				}
			}
		},
		"extends": {
			"extensions": {
				"sap.ui.controllerExtensions": {
					"sap.fe.templates.ListReport.ListReportController": {
						"controllerName": "sap.fe.core.fpmExplorer.customKPI.LRExtend"
					}
				}
			}
		},
		"rootView": {
			"viewName": "sap.fe.core.fpmExplorer.customKPI.CustomKPI"
		},
		"routing": {
			"routes": [
				{
					"pattern": ":?query:",
					"name": "sample",
					"target": "sample"
				}
			],
			"targets": {
				"sample": {
					"type": "Component",
					"id": "Default",
					"name": "sap.fe.templates.ListReport",
					"options": {
						"settings": {
							"contextPath": "/Travel",
							"variantManagement": "None",
							"initialLoad": true,
							"keyPerformanceIndicators": {
								"myKPITag": {
									"template": "sap.fe.core.fpmExplorer.customKPI.CustomKPITag"
								},
								"myKPIWithPress": {
									"template": "sap.fe.core.fpmExplorer.customKPI.CustomKPITagWithPress"
								}
							},
							"controlConfiguration": {
								"@com.sap.vocabularies.UI.v1.LineItem": {
									"tableSettings": {
										"creationMode": {
											"name": "CreationDialog",
											"creationFields": "Description, BeginDate, EndDate"
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
}
```

**STEP**: Defining the Basic KPI Tag Fragment

**DESCRIPTION**: Create a fragment that defines a basic KPI tag with static values. The KPITag building block provides properties for number, unit, and status display.

**LANGUAGE**: XML

**CODE**:
```xml
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:macros="sap.fe.macros">
	<macros:KPITag number="101" unit="RUP" status="Success" />
</core:FragmentDefinition>
```

**STEP**: Defining an Interactive KPI Tag with a Press Handler

**DESCRIPTION**: For interactive KPI tags, add a press handler that references a method in your controller extension. This allows users to click on the KPI for additional actions.

**LANGUAGE**: XML

**CODE**:
```xml
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:macros="sap.fe.macros">
	<macros:KPITag
		number="0"
		unit="Days"
		status="Error"
		showIcon="true"
		press=".extension.sap.fe.core.fpmExplorer.customKPI.LRExtend.onKPIPressed"
	/>
</core:FragmentDefinition>
```

**STEP**: Registering a Controller Extension Configuration

**DESCRIPTION**: Register your controller extension in the manifest.json file to handle KPI press events and other custom logic.

**LANGUAGE**: JSON

**CODE**:
```json
{
	"_version": "1.12.0",
	"sap.app": {
		"id": "sap.fe.core.fpmExplorer.customKPI",
		"type": "application",
		"applicationVersion": {
			"version": "1.0.0"
		},
		"dataSources": {
			"mainService": {
				"uri": "/sap/fe/core/mock/service/",
				"type": "OData",
				"settings": {
					"annotations": [],
					"odataVersion": "4.0"
				}
			}
		}
	},
	"sap.ui5": {
		"dependencies": {
			"minUI5Version": "1.111.1",
			"libs": {
				"sap.ui.core": {},
				"sap.fe.templates": {}
			}
		},
		"contentDensities": {
			"compact": true,
			"cozy": true
		},
		"models": {
			"": {
				"dataSource": "mainService",
				"settings": {
					"operationMode": "Server",
					"autoExpandSelect": true,
					"earlyRequests": true
				}
			}
		},
		"extends": {
			"extensions": {
				"sap.ui.controllerExtensions": {
					"sap.fe.templates.ListReport.ListReportController": {
						"controllerName": "sap.fe.core.fpmExplorer.customKPI.LRExtend"
					}
				}
			}
		},
		"rootView": {
			"viewName": "sap.fe.core.fpmExplorer.customKPI.CustomKPI"
		},
		"routing": {
			"routes": [
				{
					"pattern": ":?query:",
					"name": "sample",
					"target": "sample"
				}
			],
			"targets": {
				"sample": {
					"type": "Component",
					"id": "Default",
					"name": "sap.fe.templates.ListReport",
					"options": {
						"settings": {
							"contextPath": "/Travel",
							"variantManagement": "None",
							"initialLoad": true,
							"keyPerformanceIndicators": {
								"myKPITag": {
									"template": "sap.fe.core.fpmExplorer.customKPI.CustomKPITag"
								},
								"myKPIWithPress": {
									"template": "sap.fe.core.fpmExplorer.customKPI.CustomKPITagWithPress"
								}
							},
							"controlConfiguration": {
								"@com.sap.vocabularies.UI.v1.LineItem": {
									"tableSettings": {
										"creationMode": {
											"name": "CreationDialog",
											"creationFields": "Description, BeginDate, EndDate"
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
}
```

**STEP**: Implementing the Controller Extension

**DESCRIPTION**: Implement the press handler method in your controller extension to define what happens when users interact with the KPI tags.

**LANGUAGE**: TypeScript

**CODE**:
```typescript
import MessageToast from "sap/m/MessageToast";
import ControllerExtension from "sap/ui/core/mvc/ControllerExtension";

/**
 * Controller extension for custom KPI actions in the List Report floorplan.
 * @namespace sap.fe.core.fpmExplorer.customKPI
 */
export default class LRExtend extends ControllerExtension {
	/**
	 * Handles the KPI press event.
	 * Shows a message toast when the KPI is clicked.
	 */
	public onKPIPressed(): void {
		MessageToast.show("You clicked on a KPI");
	}
}
```

**ADDITIONAL RELATED CODE BLOCKS**:

**FILE**: service.cds

**LANGUAGE**: CDS

**CODE**:
```cds
using {
  sap,
  managed,
  Currency,
  Country
} from '@sap/cds/common';

using from '../service/annotations';

@cds.autoexpose  @readonly
aspect MasterData {}

service TravelService {
  @odata.draft.enabled
  @Common.SemanticKey: [TravelID]

  entity Travel : managed {
    key TravelUUID    : UUID;

        @Common.Label          : 'ID'
        @Common.Text           : Description
        TravelID      : Integer default 0                         @readonly;

        @Common.Label          : 'Begin Date'
        BeginDate     : Date;

        @Common.Label          : 'End Date'
        EndDate       : Date;

        @Common.Label          : 'Booking Fee'
        BookingFee    : Decimal(10, 2) default 0                  @Measures.ISOCurrency: CurrencyCode_code;

        @Common.Label          : 'Total Price'
        TotalPrice    : Decimal(10, 2)                            @readonly  @Measures.ISOCurrency: CurrencyCode_code;

        @Common.Label          : 'Currency'
        CurrencyCode  : Association to CurrencyCode default 'EUR' @mandatory;

        @Common.Label          : 'Description'
        Description   : String(1024);

        @Common.Label          : 'Travel Details'
        @UI.MultiLineText
        TravelDetails : String(1024);

        @title                 : 'Status'
        @Common.Text           : TravelStatus.name
        @Common.TextArrangement: #TextOnly
        TravelStatus  : Association to TravelStatus default 'O'   @readonly;

        @title                 : 'Agency'
        @Common.Text           : to_Agency.Name
        @Common.TextArrangement: #TextFirst
        to_Agency     : Association to TravelAgency               @mandatory;

        to_Booking    : Composition of many Booking
                          on to_Booking.to_Travel = $self;
  };

  entity Booking : managed {
    key BookingUUID   : UUID;

        @Common.Label: 'Booking ID'
        BookingID     : Integer                                  @Core.Computed;

        @Common.Label: 'Booking Date'
        BookingDate   : Date;

        @Common.Label: 'Connection'
        ConnectionID  : String(4)                                @mandatory;

        @Common.Label: 'Flight Date'
        FlightDate    : Date                                     @mandatory;

        @Common.Label: 'Flight Price'
        FlightPrice   : Decimal(10, 2)                           @Measures.ISOCurrency: CurrencyCode_code;

        @Common.Label: 'Currency'
        CurrencyCode  : Currency default 'EUR'                   @mandatory;

        @Common.Label: 'Status'
        BookingStatus : Association to BookingStatus default 'N' @mandatory;
        to_Travel     : Association to Travel                    @mandatory;

        PaymentMethod : String(1) default 'B'                    @Common              : {
          Label                   : 'Payment Method',
          Text                    : _Payment.Method,
          TextArrangement         : #TextOnly,
          ValueListWithFixedValues: true,
          ValueList               : {
            Label         : 'Payment Method',
            CollectionPath: 'Payment',
            Parameters    : [{
              $Type            : 'Common.ValueListParameterInOut',
              LocalDataProperty: PaymentMethod,
              ValueListProperty: 'code'
            }]
          }
        };
        _Payment      : Association to one Payment
                          on _Payment.code = PaymentMethod;
  };

  entity Payment {
    key code   : String(1) @(Common: {
          Label          : 'Payment Code',
          Text           : Method,
          TextArrangement: #TextFirst
        });
        Method : String    @(
          Core.Immutable: true,
          Common.Label  : 'Payment Method'
        );
  }

  entity TravelStatus : sap.common.CodeList {
    key code        : String(1) @Common.Text: descr;
        name        : String(255);
        descr       : String(1000);
        criticality : Int16     @odata.Type : 'Edm.Byte' enum {
          Neutral  = 0;
          Negative = 1;
          Critical = 2;
          Positive = 3;
          NewItem  = 5
        };
  };

  entity CurrencyCode : sap.common.CodeList {
        @Common.Label: 'Currency Code'
    key code  : String(3);

        @Common.Label: 'Currency Description'
        descr : String(255);
  };

  entity BookingStatus : sap.common.CodeList {
    key code : BookingStatusCode
  };

  entity TravelAgency : MasterData {
        @Common.Label: 'Agency ID'
        @Common.Text : Name
    key AgencyID       : String(6);

        @Common.Label: 'Agency Name'
        Name           : String(80);
        Street         : String(60);

        @Common.Label: 'Postal Code'
        PostalCode     : String(10);

        @Common.Label: 'City'
        City           : String(40);

        @Common.Label: 'Country Code'
        CountryCode    : Country;

        @Common.Label: 'Phone Number'
        PhoneNumber    : String(30);

        @Common.Label: 'Email Address'
        EMailAddress   : String(256);

        @Common.Label: 'Web Address'
        WebAddress     : String(256);
        Rating         : Integer;
        Recommendation : Integer;
  };

  type TravelStatusCode  : String(1) enum {
    Open     = 'O';
    Accepted = 'A';
    Canceled = 'X';
  };

  type BookingStatusCode : String(1) enum {
    New      = 'N';
    Booked   = 'B';
    Canceled = 'X';
  };
}

```

**FILE**: annotations.cds

**LANGUAGE**: CDS

**CODE**:
```cds
using TravelService as service from '../service/service';

annotate service.Travel {
  TravelStatus @Common.ValueListWithFixedValues;
  CurrencyCode @Common.ValueList: {
    CollectionPath: 'Currencies',
    Parameters    : [
      {
        $Type            : 'Common.ValueListParameterInOut',
        LocalDataProperty: CurrencyCode_code,
        ValueListProperty: 'code'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'name'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'descr'
      }
    ]
  };
}

annotate service.Travel with @UI.LineItem: [
  {Value: TravelID},
  {
    $Type : 'UI.DataFieldForAnnotation',
    Target: '@UI.ConnectedFields#TripDates'
  },
  {Value: to_Agency_AgencyID},
  {
    Value             : TravelStatus_code,
    Criticality       : TravelStatus.criticality,
    @UI.Importance    : #High,
    @HTML5.CssDefaults: {width: '10em'}
  },
  {Value: BookingFee},
  {Value: TotalPrice}
];

annotate service.Travel with @(UI: {SelectionFields: [
  TravelID,
  to_Agency_AgencyID,
  TravelStatus_code,
  BeginDate,
  EndDate
]});

annotate service.Travel with @Capabilities.FilterRestrictions.FilterExpressionRestrictions: [
  {
    Property          : 'BeginDate',
    AllowedExpressions: 'SingleRange'
  },
  {
    Property          : 'EndDate',
    AllowedExpressions: 'SingleRange'
  }
];

annotate service.Travel with @(UI: {
  FieldGroup #TravelData    : {Data: [
    {Value: TravelID},
    {Value: to_Agency_AgencyID},
    {Value: BeginDate},
    {Value: EndDate}
  ]},
  FieldGroup #ApprovalData  : {Data: [
    {
      $Type      : 'UI.DataField',
      Value      : TravelStatus_code,
      Criticality: TravelStatus.criticality,
      Label      : 'Status'
    },
    {Value: BookingFee},
    {Value: TotalPrice}
  ]},
  FieldGroup #HeaderMain    : {Data: [
    {Value: BeginDate},
    {Value: EndDate},
    {Value: TotalPrice}
  ]},
  ConnectedFields #TripDates: {
    Label   : 'Business Trip Dates',
    Template: '{BeginDate} / {EndDate}',
    Data    : {
      BeginDate: {
        $Type: 'UI.DataField',
        Value: BeginDate
      },
      EndDate  : {
        $Type: 'UI.DataField',
        Value: EndDate
      }
    }
  },
  Facets                    : [
    {
      $Type : 'UI.ReferenceFacet',
      ID    : 'TravelData',
      Label : 'Travel Information',
      Target: '@UI.FieldGroup#TravelData',
    },
    {
      $Type : 'UI.ReferenceFacet',
      ID    : 'ApprovalData',
      Label : 'Approval Data',
      Target: '@UI.FieldGroup#ApprovalData'
    },
    {
      $Type : 'UI.ReferenceFacet',
      ID    : 'BookingList',
      Label : 'Bookings',
      Target: 'to_Booking/@UI.LineItem'
    }
  ],
  HeaderFacets              : [{
    $Type : 'UI.ReferenceFacet',
    Target: '@UI.FieldGroup#HeaderMain'
  }],
  HeaderInfo                : {
    TypeName      : 'Travel',
    TypeNamePlural: 'Travels',
    Title         : {
      $Type: 'UI.DataField',
      Value: Description
    },
    Description   : {
      $Type: 'UI.DataField',
      Value: TravelID
    },
    TypeImageUrl  : 'sap-icon://header',
  }
});

annotate service.Travel {
  to_Agency @Common.ValueList: {
    CollectionPath: 'TravelAgency',
    Label         : '',
    Parameters    : [
      {
        $Type            : 'Common.ValueListParameterInOut',
        LocalDataProperty: to_Agency_AgencyID,
        ValueListProperty: 'AgencyID'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'Name'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'Street'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'PostalCode'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'City'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'CountryCode_code'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'PhoneNumber'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'EMailAddress'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'WebAddress'
      }
    ]
  };
}

annotate service.TravelAgency with @(UI: {
  DataPoint #Recommendation: {
    Value        : Recommendation,
    TargetValue  : 100.0,
    Title        : 'Recommendation',
    Visualization: #Progress
  },
  DataPoint #Rating        : {
    Value        : Rating,
    TargetValue  : 5.0,
    Title        : 'Rating',
    Visualization: #Rating
  },
  FieldGroup #Contact      : {Data: [{
    $Type : 'UI.DataFieldForAnnotation',
    Target: '@Communication.Contact',
    Label : 'Travel Agency'
  }]}
});

annotate service.TravelAgency with @(
  Communication.Contact : {
    email: [{
      type   : #work,
      address: EMailAddress
    }],
    fn   : Name,
    adr  : [{
      type    : #work,
      code    : PostalCode,
      country : CountryCode_code,
      locality: City
    }]
  },
  Common.IsNaturalPerson: false
);

annotate service.Booking {
  CurrencyCode @Common.ValueList: {
    CollectionPath: 'Currencies',
    Parameters    : [
      {
        $Type            : 'Common.ValueListParameterInOut',
        LocalDataProperty: CurrencyCode_code,
        ValueListProperty: 'code'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'name'
      },
      {
        $Type            : 'Common.ValueListParameterDisplayOnly',
        ValueListProperty: 'descr'
      }
    ]
  };
}

annotate service.Booking with @(UI: {
  HeaderInfo: {
    TypeName      : 'Booking',
    TypeNamePlural: 'Bookings',
    TypeImageUrl  : 'sap-icon://alert',
    Title         : {
      $Type: 'UI.DataField',
      Value: BookingID
    }
  },
  Facets    : [{
    $Type : 'UI.ReferenceFacet',
    ID    : 'FacetIdentifier1',
    Target: '@UI.FieldGroup'
  }],
  LineItem  : [
    {Value: BookingID},
    {Value: BookingDate},
    {Value: ConnectionID},
    {Value: FlightDate},
    {Value: FlightPrice}
  ],
  FieldGroup: {Data: [
    {
      $Type: 'UI.DataField',
      Value: BookingID
    },
    {
      $Type: 'UI.DataField',
      Value: BookingDate
    },
    {
      $Type: 'UI.DataField',
      Value: FlightDate
    },
    {
      $Type: 'UI.DataField',
      Value: FlightPrice
    }
  ]}
});

annotate service.TravelAgency with @(UI: {FieldGroup #Link: {Data: [{
  $Type: 'UI.DataFieldWithUrl',
  Value: Name,
  Url  : WebAddress
}]}});

```

**FILE**: Travel.json

**LANGUAGE**: JSON

**CODE**:
```json
[
	{
		"TravelUUID": "52657221A8E4645C17002DF03754AB66",
		"TravelID": "00000001",
		"BeginDate": "2025-11-04",
		"EndDate": "2025-11-06",
		"BookingFee": "20.00",
		"TotalPrice": "900.00",
		"CurrencyCode_code": "USD",
		"Description": "Business Trip for Christine, Pierre",
		"TravelDetails": "This business trip includes a two-day customer workshop at the airport. The goal is the evaluation of the customer's use cases and the alignment on the road map for the upcoming year.",
		"TravelStatus_code": "A",
		"to_Agency_AgencyID": "070001"
	},
	{
		"TravelUUID": "53657221A8E4645C17002DF03754AB66",
		"TravelID": "00000002",
		"BeginDate": "2025-12-04",
		"EndDate": "2025-12-16",
		"BookingFee": "80.00",
		"TotalPrice": "3164.00",
		"CurrencyCode_code": "USD",
		"Description": "Lars Jensen site visit for system rollout support",
		"TravelDetails": "Will be provided soon...",
		"TravelStatus_code": "O",
		"to_Agency_AgencyID": "070002"
	},
	{
		"TravelUUID": "54657221A8E4645C17002DF03754AB66",
		"TravelID": "00000003",
		"BeginDate": "2025-08-04",
		"EndDate": "2025-08-08",
		"BookingFee": "40.00",
		"TotalPrice": "1871.00",
		"CurrencyCode_code": "USD",
		"Description": "John Smith customer workshop at Acme Corp headquarters",
		"TravelDetails": "Will be provided soon...",
		"TravelStatus_code": "O",
		"to_Agency_AgencyID": "070003"
	},
	{
		"TravelUUID": "55657221A8E4645C17002DF03754AB66",
		"TravelID": "00000004",
		"BeginDate": "2025-09-04",
		"EndDate": "2025-09-05",
		"BookingFee": "40.00",
		"TotalPrice": "1240.00",
		"CurrencyCode_code": "USD",
		"Description": "Anna Müller onboarding with new project team in Berlin",
		"TravelDetails": "Will be provided soon...",
		"TravelStatus_code": "X",
		"to_Agency_AgencyID": "070003"
	}
]

```

Custom KPI Tag

custom KPI
KPI tags
list report
metrics
performance indicators


**TITLE**: Custom View

**INTRODUCTION**: No introduction

**TAGS**: custom view, list report, view customization, extensions

**STEP**: Defining View Settings in the Manifest

**DESCRIPTION**: You define the views that appear on top of the table in the list report page with settings in the page definition area of the manifest.

**LANGUAGE**: JSON

**CODE**:
```json
{
	"_version": "1.12.0",
	"sap.app": {
		"id": "sap.fe.core.fpmExplorer.customViewListReport",
		"type": "application",
		"i18n": {
			"bundleUrl": "i18n/i18n.properties",
			"supportedLocales": [""],
			"fallbackLocale": ""
		},
		"applicationVersion": {
			"version": "1.0.0"
		},
		"dataSources": {
			"mainService": {
				"uri": "/sap/fe/core/mock/customViewListReport/",
				"type": "OData",
				"settings": {
					"annotations": [],
					"odataVersion": "4.0"
				}
			}
		}
	},
	"sap.ui5": {
		"dependencies": {
			"minUI5Version": "1.111.1",
			"libs": {
				"sap.ui.core": {},
				"sap.fe.templates": {}
			}
		},
		"contentDensities": {
			"compact": true,
			"cozy": true
		},
		"models": {
			"i18n": {
				"type": "sap.ui.model.resource.ResourceModel",
				"settings": {
					"bundleName": "sap.fe.core.fpmExplorer.customViewListReport.i18n.i18n"
				}
			},
			"@i18n": {
				"type": "sap.ui.model.resource.ResourceModel",
				"settings": {
					"bundleName": "sap.fe.core.fpmExplorer.customViewListReport.i18n.i18n"
				}
			},
			"": {
				"dataSource": "mainService",
				"settings": {
					"operationMode": "Server",
					"autoExpandSelect": true,
					"earlyRequests": true
				}
			}
		},
		"extends": {
			"extensions": {
				"sap.ui.controllerExtensions": {
					"sap.fe.templates.ListReport.ListReportController": {
						"controllerName": "sap.fe.core.fpmExplorer.customViewListReport.LRExtend"
					}
				}
			}
		},
		"rootView": {
			"viewName": "sap.fe.core.fpmExplorer.customViewListReport.CustomViewListReport"
		},
		"routing": {
			"routes": [
				{
					"pattern": ":?query:",
					"name": "listPage",
					"target": "listPage"
				}
			],
			"targets": {
				"listPage": {
					"type": "Component",
					"id": "Default",
					"name": "sap.fe.templates.ListReport",
					"options": {
						"settings": {
							"contextPath": "/Travel",
							"variantManagement": "None",
							"initialLoad": true,
							"controlConfiguration": {
								"@com.sap.vocabularies.UI.v1.SelectionFields": {
									"showClearButton": true
								},
								"@com.sap.vocabularies.UI.v1.LineItem": {
									"tableSettings": {
										"creationMode": {
											"name": "CreationDialog",
											"creationFields": "Description, BeginDate, EndDate"
										}
									}
								}
							},
							"views": {
								"paths": [
									{
										"key": "tab1",
										"annotationPath": "com.sap.vocabularies.UI.v1.SelectionPresentationVariant#All"
									},
									{
										"key": "tab2",
										"label": "Custom View with List control",
										"template": "sap.fe.core.fpmExplorer.customViewListReport.CustomViewWithList"
									}
								],
								"showCounts": true
							}
						}
					}
				}
			}
		}
	}
}
```

**STEP**: Defining Extension Settings in the Manifest

**DESCRIPTION**: You define the controller used for the extension in the extensions section of the manifest.

**LANGUAGE**: JSON

**CODE**:
```json
{
	"_version": "1.12.0",
	"sap.app": {
		"id": "sap.fe.core.fpmExplorer.customViewListReport",
		"type": "application",
		"i18n": {
			"bundleUrl": "i18n/i18n.properties",
			"supportedLocales": [""],
			"fallbackLocale": ""
		},
		"applicationVersion": {
			"version": "1.0.0"
		},
		"dataSources": {
			"mainService": {
				"uri": "/sap/fe/core/mock/customViewListReport/",
				"type": "OData",
				"settings": {
					"annotations": [],
					"odataVersion": "4.0"
				}
			}
		}
	},
	"sap.ui5": {
		"dependencies": {
			"minUI5Version": "1.111.1",
			"libs": {
				"sap.ui.core": {},
				"sap.fe.templates": {}
			}
		},
		"contentDensities": {
			"compact": true,
			"cozy": true
		},
		"models": {
			"i18n": {
				"type": "sap.ui.model.resource.ResourceModel",
				"settings": {
					"bundleName": "sap.fe.core.fpmExplorer.customViewListReport.i18n.i18n"
				}
			},
			"@i18n": {
				"type": "sap.ui.model.resource.ResourceModel",
				"settings": {
					"bundleName": "sap.fe.core.fpmExplorer.customViewListReport.i18n.i18n"
				}
			},
			"": {
				"dataSource": "mainService",
				"settings": {
					"operationMode": "Server",
					"autoExpandSelect": true,
					"earlyRequests": true
				}
			}
		},
		"extends": {
			"extensions": {
				"sap.ui.controllerExtensions": {
					"sap.fe.templates.ListReport.ListReportController": {
						"controllerName": "sap.fe.core.fpmExplorer.customViewListReport.LRExtend"
					}
				}
			}
		},
		"rootView": {
			"viewName": "sap.fe.core.fpmExplorer.customViewListReport.CustomViewListReport"
		},
		"routing": {
			"routes": [
				{
					"pattern": ":?query:",
					"name": "listPage",
					"target": "listPage"
				}
			],
			"targets": {
				"listPage": {
					"type": "Component",
					"id": "Default",
					"name": "sap.fe.templates.ListReport",
					"options": {
						"settings": {
							"contextPath": "/Travel",
							"variantManagement": "None",
							"initialLoad": true,
							"controlConfiguration": {
								"@com.sap.vocabularies.UI.v1.SelectionFields": {
									"showClearButton": true
								},
								"@com.sap.vocabularies.UI.v1.LineItem": {
									"tableSettings": {
										"creationMode": {
											"name": "CreationDialog",
											"creationFields": "Description, BeginDate, EndDate"
										}
									}
								}
							},
							"views": {
								"paths": [
									{
										"key": "tab1",
										"annotationPath": "com.sap.vocabularies.UI.v1.SelectionPresentationVariant#All"
									},
									{
										"key": "tab2",
										"label": "Custom View with List control",
										"template": "sap.fe.core.fpmExplorer.customViewListReport.CustomViewWithList"
									}
								],
								"showCounts": true
							}
						}
					}
				}
			}
		}
	}
}
```

**STEP**: Referencing the table in the Selection Presentation Variants

**DESCRIPTION**: You define selection presentation variants by using the UI.SelectionPresentationVariant in your service implementation. The selection presentation variant points to the UI.SelectionVariant and UI.PresentationVariant annotations.

**LANGUAGE**: CDS

**CODE**:
```cds
using {TravelService.Travel} from '../../../../../service/service';
using from '../../../../../service/annotations';

annotate TravelService.Travel with @(UI: {
  PresentationVariant              : {Visualizations: ['@UI.LineItem']},
  SelectionPresentationVariant #All: {
    Text               : 'All',
    SelectionVariant   : {
      Text         : 'All',
      SelectOptions: [{PropertyName: TravelID}]
    },
    PresentationVariant: {
      SortOrder     : [{Property: Description}],
      Visualizations: ['@UI.LineItem']
    }
  }
});
```

**LANGUAGE**: XML

**CODE**:
```xml
<Annotation Term="UI.SelectionPresentationVariant" Qualifier="All">
	<Record Type="UI.SelectionPresentationVariantType">
		<PropertyValue Property="Text" String="All" />
		<PropertyValue Property="SelectionVariant">
			<Record Type="UI.SelectionVariantType">
				<PropertyValue Property="Text" String="All" />
				<PropertyValue Property="SelectOptions">
					<Collection>
						<Record Type="UI.SelectOptionType">
							<PropertyValue Property="PropertyName" PropertyPath="TravelID" />
						</Record>
					</Collection>
				</PropertyValue>
			</Record>
		</PropertyValue>
		<PropertyValue Property="PresentationVariant">
			<Record Type="UI.PresentationVariantType">
				<PropertyValue Property="SortOrder">
					<Collection>
						<Record Type="Common.SortOrderType">
							<PropertyValue Property="Property" PropertyPath="Description" />
						</Record>
					</Collection>
				</PropertyValue>
				<PropertyValue Property="Visualizations">
					<Collection>
						<AnnotationPath>@UI.LineItem</AnnotationPath>
					</Collection>
				</PropertyValue>
			</Record>
		</PropertyValue>
	</Record>
</Annotation>
```

**ADDITIONAL RELATED CODE BLOCKS**:

**FILE**: LRExtend.controller.ts

**LANGUAGE**: TypeScript

**CODE**:
```typescript
import BaseControllerExtension from "sap/fe/core/controllerextensions/BaseControllerExtension";
import type ListReportController from "sap/fe/templates/ListReport/ListReportController.controller";
import Filter from "sap/ui/model/Filter";
import type ODatav4ListBinding from "sap/ui/model/odata/v4/ODataListBinding";

/**
 * Controller extension for custom view List Report functionality.
 * @namespace sap.fe.core.fpmExplorer.customViewListReport
 */
export default class LRExtend extends BaseControllerExtension<ListReportController> {
	static overrides = BaseControllerExtension.createExtensionOverrides<LRExtend, ListReportController>({
		/**
		 * Initialization hook that gets called when the controller is initialized.
		 */
		onViewNeedsRefresh(mParameters: any): void {
			const filterInfo = mParameters.filterConditions;
			// Prepare binding info with filter/search parameters
			if (filterInfo) {
				const duplicateFilterInfo = Object.assign({}, filterInfo);
				const travelList = this.base.getExtensionAPI().byId("fe::CustomTab::tab2--customViewWithTableList");
				const binding = travelList?.getBinding("items") as ODatav4ListBinding;
				const convertedFilter = this.base.getExtensionAPI().createFiltersFromFilterConditions(duplicateFilterInfo) as any;
				if (convertedFilter) {
					const filter = new Filter({ filters: convertedFilter.filters, and: true });
					binding.filter(filter);
					binding.changeParameters({ $search: convertedFilter.search });
				}
			}
		}
	});
}

```

**FILE**: CustomViewWithList.fragment.xml

**LANGUAGE**: XML

**CODE**:
```xml
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core">
	<List id="customViewWithTableList" items="{path: '/Travel', sorter: {path: 'TravelID'}}">
		<headerToolbar>
			<OverflowToolbar>
				<content>
					<Title text="Travel Entities" level="H2" />
					<ToolbarSpacer />
				</content>
			</OverflowToolbar>
		</headerToolbar>
		<infoToolbar>
			<OverflowToolbar>
				<Label text="List of Travel entities" />
			</OverflowToolbar>
		</infoToolbar>

		<items>
			<StandardListItem title="{TravelID}" description="{Description}" />
		</items>
	</List>
</core:FragmentDefinition>

```

**FILE**: Travel.json

**LANGUAGE**: JSON

**CODE**:
```json
[
	{
		"TravelUUID": "52657221A8E4645C17002DF03754AB66",
		"TravelID": "00000001",
		"BeginDate": "2025-11-04",
		"EndDate": "2025-11-06",
		"BookingFee": "20.00",
		"TotalPrice": "900.00",
		"CurrencyCode_code": "USD",
		"Description": "Business Trip for Christine, Pierre",
		"TravelDetails": "This business trip includes a two-day customer workshop at the airport. The goal is the evaluation of the customer's use cases and the alignment on the road map for the upcoming year.",
		"TravelStatus_code": "A",
		"to_Agency_AgencyID": "070001"
	},
	{
		"TravelUUID": "53657221A8E4645C17002DF03754AB66",
		"TravelID": "00000002",
		"BeginDate": "2025-12-04",
		"EndDate": "2025-12-16",
		"BookingFee": "80.00",
		"TotalPrice": "3164.00",
		"CurrencyCode_code": "USD",
		"Description": "Lars Jensen site visit for system rollout support",
		"TravelDetails": "Will be provided soon...",
		"TravelStatus_code": "O",
		"to_Agency_AgencyID": "070002"
	},
	{
		"TravelUUID": "54657221A8E4645C17002DF03754AB66",
		"TravelID": "00000003",
		"BeginDate": "2025-08-04",
		"EndDate": "2025-08-08",
		"BookingFee": "40.00",
		"TotalPrice": "1871.00",
		"CurrencyCode_code": "USD",
		"Description": "John Smith customer workshop at Acme Corp headquarters",
		"TravelDetails": "Will be provided soon...",
		"TravelStatus_code": "O",
		"to_Agency_AgencyID": "070003"
	},
	{
		"TravelUUID": "55657221A8E4645C17002DF03754AB66",
		"TravelID": "00000004",
		"BeginDate": "2025-09-04",
		"EndDate": "2025-09-05",
		"BookingFee": "40.00",
		"TotalPrice": "1240.00",
		"CurrencyCode_code": "USD",
		"Description": "Anna Müller onboarding with new project team in Berlin",
		"TravelDetails": "Will be provided soon...",
		"TravelStatus_code": "X",
		"to_Agency_AgencyID": "070003"
	}
]

```

**FILE**: TravelAgency.json

**LANGUAGE**: JSON

**CODE**:
```json
[
	{
		"AgencyID": "070001",
		"City": "Rochester",
		"CountryCode_code": "US",
		"EMailAddress": "info@sunshine-travel.sap",
		"Name": "Sunshine Travel",
		"PhoneNumber": "+1 901-632-5620",
		"PostalCode": "54323",
		"Street": "134 West Street",
		"WebAddress": "http://www.sunshine-travel.sap",
		"Rating": "4",
		"Recommendation": "88"
	},
	{
		"AgencyID": "070002",
		"City": "Duesseldorf",
		"CountryCode_code": "DE",
		"EMailAddress": "info@flyhigh.sap",
		"Name": "Fly High",
		"PhoneNumber": "+49 2102 69555",
		"PostalCode": "40880",
		"Street": "Berliner Allee 11",
		"WebAddress": "http://www.flyhigh.sap",
		"Rating": "5",
		"Recommendation": "98"
	},
	{
		"AgencyID": "070003",
		"City": "Berlin",
		"CountryCode_code": "DE",
		"EMailAddress": "info@haphop.sap",
		"Name": "Happy Hopping",
		"PhoneNumber": "+49 30-8853-0",
		"PostalCode": "13467",
		"Street": "Calvinstr. 36",
		"WebAddress": "http://www.haphop.sap",
		"Rating": "4",
		"Recommendation": "91"
	},
	{
		"AgencyID": "070004",
		"City": "Frankfurt",
		"CountryCode_code": "DE",
		"EMailAddress": "info@pinkpanther.sap",
		"Name": "Pink Panther",
		"PhoneNumber": "+49 69-467653-0",
		"PostalCode": "65936",
		"Street": "Auf der Schanz 54",
		"WebAddress": "http://www.pinkpanther.sap",
		"Rating": "5",
		"Recommendation": "97"
	},
	{
		"AgencyID": "070005",
		"City": "Nuernberg",
		"CountryCode_code": "DE",
		"EMailAddress": "info@yc.sap",
		"Name": "Your Choice",
		"PhoneNumber": "+49 9256-4548-0",
		"PostalCode": "90455",
		"Street": "Gustav-Jung-Str. 425",
		"WebAddress": "http://www.yc.sap",
		"Rating": "4",
		"Recommendation": "82"
	},
	{
		"AgencyID": "070006",
		"City": "Roma",
		"CountryCode_code": "IT",
		"EMailAddress": "info@tours.it/Adventure/",
		"Name": "Bella Italia",
		"PhoneNumber": "+39 6 893546721",
		"PostalCode": "00139",
		"Street": "Via Marconi 123",
		"WebAddress": "http://www.tours.it/Adventure/",
		"Rating": "5",
		"Recommendation": "95"
	},
	{
		"AgencyID": "070007",
		"City": "Sydney",
		"CountryCode_code": "AU",
		"EMailAddress": "info@hst.co.au",
		"Name": "Hot Socks Travel",
		"PhoneNumber": "+61 2 2004 5000",
		"PostalCode": "8053",
		"Street": "224 Balnagask Rd",
		"WebAddress": "http://www.hst.co.au",
		"Rating": "5",
		"Recommendation": "99"
	},
	{
		"AgencyID": "070008",
		"City": "Singapore",
		"CountryCode_code": "SG",
		"EMailAddress": "info@burns-burns-burns.sg",
		"Name": "Burns Nuclear",
		"PhoneNumber": "+65 777-5566",
		"PostalCode": "118228",
		"Street": "14 Science Park Drive",
		"WebAddress": "http://www.burns-burns-burns.sg",
		"Rating": "4",
		"Recommendation": "84"
	},
	{
		"AgencyID": "070009",
		"City": "Neumarkt",
		"CountryCode_code": "AT",
		"EMailAddress": "info@honauer.at",
		"Name": "Honauer Reisen GmbH",
		"PhoneNumber": "+43 7941 8903",
		"PostalCode": "4212",
		"Street": "Baumgarten 8",
		"WebAddress": "http://www.honauer.at",
		"Rating": "5",
		"Recommendation": "99"
	},
	{
		"AgencyID": "070010",
		"City": "Berlin",
		"CountryCode_code": "DE",
		"EMailAddress": "info@travel-from-walldorf",
		"Name": "Travel from Walldorf",
		"PhoneNumber": "+49 30-622860",
		"PostalCode": "10557",
		"Street": "Altonaer Str. 24",
		"WebAddress": "http://www.travel-from-walldorf",
		"Rating": "4",
		"Recommendation": "90"
	},
	{
		"AgencyID": "070011",
		"City": "Stockholm",
		"CountryCode_code": "SE",
		"EMailAddress": "info@starfleet.ufp",
		"Name": "Voyager Enterprises",
		"PhoneNumber": "+46 8/ 587 70000",
		"PostalCode": "70563",
		"Street": "Gustavslundsvaegen 151",
		"WebAddress": "http://www.starfleet.ufp",
		"Rating": "5",
		"Recommendation": "100"
	},
	{
		"AgencyID": "070012",
		"City": "Birmingham",
		"CountryCode_code": "GB",
		"EMailAddress": "info@ben-mcCloskey.co.uk",
		"Name": "Ben McCloskey Ltd.",
		"PhoneNumber": "+44 121 365-2251",
		"PostalCode": "B17 9TN",
		"Street": "74 Court Oak Rd",
		"WebAddress": "http://www.ben-mcCloskey.co.uk",
		"Rating": "5",
		"Recommendation": "97"
	},
	{
		"AgencyID": "070013",
		"City": "Zuerich",
		"CountryCode_code": "CH",
		"EMailAddress": "info@pi-pa-tri.sap",
		"Name": "Pillepalle Trips",
		"PhoneNumber": "+41 1 345-5321",
		"PostalCode": "8008",
		"Street": "Gorki Park 4",
		"WebAddress": "http://www.pi-pa-tri.sap",
		"Rating": "5",
		"Recommendation": "99"
	},
	{
		"AgencyID": "070014",
		"City": "London",
		"CountryCode_code": "GB",
		"EMailAddress": "info@hopp.sap",
		"Name": "Kangeroos",
		"PhoneNumber": "+44 171-2937638",
		"PostalCode": "20001",
		"Street": "Lancaster drive 435",
		"WebAddress": "http://www.hopp.sap",
		"Rating": "4",
		"Recommendation": "85"
	},
	{
		"AgencyID": "070015",
		"City": "Dresden",
		"CountryCode_code": "DE",
		"EMailAddress": "info@neu.schwanstein.sap",
		"Name": "Bavarian Castle",
		"PhoneNumber": "+49 98-32832732",
		"PostalCode": "01069",
		"Street": "Pilnizerstr. 241",
		"WebAddress": "http://www.neu.schwanstein.sap",
		"Rating": "4",
		"Recommendation": "91"
	},
	{
		"AgencyID": "070016",
		"City": "Boston",
		"CountryCode_code": "US",
		"EMailAddress": "info@ali.sap",
		"Name": "Ali's Bazar",
		"PhoneNumber": "+1 508-692-5200",
		"PostalCode": "19113",
		"Street": "45, Mac Arthur Boulevard",
		"WebAddress": "http://www.ali.sap",
		"Rating": "4",
		"Recommendation": "87"
	},
	{
		"AgencyID": "070017",
		"City": "Glasgow",
		"CountryCode_code": "GB",
		"EMailAddress": "info@super.sap",
		"Name": "Super Agency",
		"PhoneNumber": "+44 141 711-5643",
		"PostalCode": "G12 8AG",
		"Street": "50 Cranworth St",
		"WebAddress": "http://www.super.sap",
		"Rating": "5",
		"Recommendation": "96"
	},
	{
		"AgencyID": "070018",
		"City": "Moscow",
		"CountryCode_code": "RU",
		"EMailAddress": "info@wang.chong.sap",
		"Name": "Wang Chong",
		"PhoneNumber": "+7 3287-213321",
		"PostalCode": "150021",
		"Street": "Gagarine Park",
		"WebAddress": "http://www.wang.chong.sap",
		"Rating": "3",
		"Recommendation": "48"
	},
	{
		"AgencyID": "070019",
		"City": "Hannover",
		"CountryCode_code": "DE",
		"EMailAddress": "info@atw.sap",
		"Name": "Around the World",
		"PhoneNumber": "+49 511-347589-0",
		"PostalCode": "30625",
		"Street": "An der Breiten Wiese 122",
		"WebAddress": "http://www.atw.sap",
		"Rating": "4",
		"Recommendation": "88"
	},
	{
		"AgencyID": "070020",
		"City": "Koeln",
		"CountryCode_code": "DE",
		"EMailAddress": "info@bye-bye.sap",
		"Name": "No Return",
		"PhoneNumber": "+49 221-5689-100",
		"PostalCode": "51105",
		"Street": "Wahnheider Str. 57",
		"WebAddress": "http://www.bye-bye.sap",
		"Rating": "5",
		"Recommendation": "94"
	}
]

```

**FILE**: TravelStatus.json

**LANGUAGE**: JSON

**CODE**:
```json
[
	{
		"code": "O",
		"name": "Open",
		"descr": "Open",
		"fieldControl": 7,
		"createDeleteHidden": false,
		"insertDeleteRestriction": true,
		"criticality": 5
	},
	{
		"code": "A",
		"name": "Accepted",
		"descr": "Accepted",
		"fieldControl": 1,
		"createDeleteHidden": true,
		"insertDeleteRestriction": false,
		"criticality": 3
	},
	{
		"code": "X",
		"name": "Canceled",
		"descr": "Canceled",
		"fieldControl": 7,
		"createDeleteHidden": true,
		"insertDeleteRestriction": false,
		"criticality": 1
	}
]

```

**FILE**: Currencies.json

**LANGUAGE**: JSON

**CODE**:
```json
[
	{
		"code": "EUR",
		"symbol": "€",
		"name": "Euro",
		"descr": "European Euro",
		"numcode": "978",
		"minor": "Cent",
		"exponent": "2"
	},
	{
		"code": "USD",
		"symbol": "$",
		"name": "US Dollar",
		"descr": "United States Dollar",
		"numcode": "840",
		"minor": "Cent",
		"exponent": "2"
	},
	{
		"code": "CAD",
		"symbol": "$",
		"name": "Canadian Dollar",
		"descr": "Canadian Dollar",
		"numcode": "124",
		"minor": "Cent",
		"exponent": "2"
	},
	{
		"code": "AUD",
		"symbol": "$",
		"name": "Australian Dollar",
		"descr": "Australian Dollar",
		"numcode": "036",
		"minor": "Cent",
		"exponent": "2"
	},
	{
		"code": "GBP",
		"symbol": "£",
		"name": "British Pound",
		"descr": "Great Britain Pound",
		"numcode": "826",
		"minor": "Penny",
		"exponent": "2"
	},
	{
		"code": "ILS",
		"symbol": "₪",
		"name": "Shekel",
		"descr": "Israeli New Shekel",
		"numcode": "376",
		"minor": "Agorat",
		"exponent": "2"
	},
	{
		"code": "INR",
		"symbol": "₹",
		"name": "Rupee",
		"descr": "Indian Rupee",
		"numcode": "356",
		"minor": "Paise",
		"exponent": "2"
	},
	{
		"code": "QAR",
		"symbol": "﷼",
		"name": "Riyal",
		"descr": "Katar Riyal",
		"numcode": "356",
		"minor": "Dirham",
		"exponent": "2"
	},
	{
		"code": "SAR",
		"symbol": "﷼",
		"name": "Riyal",
		"descr": "Saudi Riyal",
		"numcode": "682",
		"minor": "Halala",
		"exponent": "2"
	},
	{
		"code": "JPY",
		"symbol": "¥",
		"name": "Yen",
		"descr": "Japanese Yen",
		"numcode": "392",
		"minor": "Sen",
		"exponent": "2"
	},
	{
		"code": "CNY",
		"symbol": "¥",
		"name": "Yuan",
		"descr": "Chinese Yuan Renminbi",
		"numcode": "156",
		"minor": "Jiao",
		"exponent": "1"
	},
	{
		"code": "SGD",
		"symbol": "S$",
		"name": "Singapore Dollar",
		"descr": "Singapore Dollar",
		"numcode": "702",
		"minor": "Cent",
		"exponent": "2"
	},
	{
		"code": "ZAR",
		"symbol": "R",
		"name": "Rand",
		"descr": "South African Rand",
		"numcode": "710",
		"minor": "Cent",
		"exponent": "2"
	}
]

```

Custom View

custom view
list report
view customization
extensions


**TITLE**: Flexible Column Layout

**INTRODUCTION**: Apps can show up to three pages on a single screen using a column-based format. In the sample below, a list of items is shown in the first column, and when you choose an item to see its details, the related object page is shown in the second column.

**TAGS**: flexible column layout, fcl, list report, multi-column

**STEP**: Routing Configuration

**DESCRIPTION**: You can configure the column layout within the manifest.

**STEP**: Routing Routes

**DESCRIPTION**: The route target for the object page contains both the list report and the object page.

**STEP**: Page Control Aggregation

**DESCRIPTION**: Here’s how to set the controlAggregation for each page:

**ADDITIONAL RELATED CODE BLOCKS**:

**FILE**: manifest.json

**LANGUAGE**: JSON

**CODE**:
```json
{
	"_version": "1.12.0",
	"sap.app": {
		"id": "sap.fe.core.fpmExplorer.fclListReport",
		"type": "application",
		"i18n": {
			"bundleUrl": "i18n/i18n.properties",
			"supportedLocales": [""],
			"fallbackLocale": ""
		},
		"applicationVersion": {
			"version": "1.0.0"
		},
		"dataSources": {
			"mainService": {
				"uri": "/sap/fe/core/mock/service/",
				"type": "OData",
				"settings": {
					"annotations": [],
					"odataVersion": "4.0"
				}
			}
		}
	},
	"sap.ui5": {
		"dependencies": {
			"minUI5Version": "1.111.1",
			"libs": {
				"sap.ui.core": {},
				"sap.fe.templates": {}
			}
		},
		"contentDensities": {
			"compact": true,
			"cozy": true
		},
		"models": {
			"": {
				"dataSource": "mainService",
				"settings": {
					"operationMode": "Server",
					"autoExpandSelect": true,
					"earlyRequests": true
				}
			}
		},
		"rootView": {
			"viewName": "sap.fe.core.fpmExplorer.fclListReport.FclListReport",
			"type": "XML",
			"async": true,
			"id": "appRootView"
		},
		"routing": {
			"config": {
				"flexibleColumnLayout": {
					"defaultTwoColumnLayoutType": "TwoColumnsMidExpanded",
					"defaultThreeColumnLayoutType": "ThreeColumnsMidExpanded"
				},
				"routerClass": "sap.f.routing.Router"
			},
			"routes": [
				{
					"pattern": ":?query:",
					"name": "default",
					"target": ["listPage"]
				},
				{
					"pattern": "/Travel({key}):?query:",
					"name": "objectPage",
					"target": ["listPage", "objectPage"]
				}
			],
			"targets": {
				"listPage": {
					"type": "Component",
					"id": "Default",
					"name": "sap.fe.templates.ListReport",
					"controlAggregation": "beginColumnPages",
					"contextPattern": "",
					"options": {
						"settings": {
							"contextPath": "/Travel",
							"variantManagement": "Page",
							"initialLoad": "Enabled",
							"navigation": {
								"Travel": {
									"detail": {
										"route": "objectPage"
									}
								}
							}
						}
					}
				},
				"objectPage": {
					"type": "Component",
					"id": "objectPage",
					"name": "sap.fe.templates.ObjectPage",
					"controlAggregation": "midColumnPages",
					"contextPattern": "/Travel({key})",
					"options": {
						"settings": {
							"contextPath": "/Travel",
							"navigation": {}
						}
					}
				}
			}
		}
	}
}

```

Flexible Column Layout

flexible column layout
fcl
list report
multi-column