Display a 'one to many' association with SAP Fiori annotations in CAP

3k views Asked by At

I try do do a DB project with SAP cap. I want to display all entities associated with the Parent entity. If the Association is one to one it works fine. But if it is one to many it doesn't display anything.

--I have following Schema definition:

entity Company{
key ID : Integer @title: 'Company ID';
cName : String @title: 'Company name';
pers: Association to many Person on pers.comp = $self; //association to one works
}


entity Person{
    key ID : Integer @title: 'ID';
    pName: String @titel: 'Name';
    comp: Association to Company;
}

--And following fiori Annotations:

annotate Admin.Company with @(
UI.LineItem:[
    {$Type: 'UI.DataField', Value: cName},

],
UI.HeaderInfo:{
    TypeName: 'Company',
TypeNamePlural: 'Companys'
},

);

//Details view:
annotate Admin.Company with @(
UI: {
        HeaderInfo: {
    Description: {Value: ID}
    },
        HeaderFacets: [
        {$Type: 'UI.ReferenceFacet', Target: '@UI.FieldGroup#Comp'},
        ],
        Facets: [
             {$Type: 'UI.ReferenceFacet', Target: '@UI.FieldGroup#Pers'}
        ],
        FieldGroup#Comp: {
            Data: [
                {Value: cName},
            ]
        },
        FieldGroup#Pers: {
            Data: [
                {Value: pers.pName},
            ]
        },
    });

The Admin Service is just a projection on the given entities.
Does anyone know what I have to change to get pers.Name displayed in a list or something like that?
As already mentioned if I change in Schema definition 'association to many' into 'association to one' it works. But I want it to have more than one entity associated.

1

There are 1 answers

0
mxmlndml On

If you are using the Fiori Elements List Report Object Page template I think you can only use a 1:1 association. This is the intended design of the floorplan (List → Detail). How should Fiori Elements know which of the "many" person items should be bound to the one detail view.

However, what you can and probably want to do is binding the detail view to the selected company item and create a field group. There you can display a table which refers to a different entity. So, you keep your schema.cds as it currently is but change your annotation.cds:

annotate Admin.Company with @(
  UI: {
    // columns of the list view
    LineItem:[
      {$Type: 'UI.DataField', Value: cName},
    ],
    // title (singular/plural) of the list view and description of the detail view
    HeaderInfo:{
      TypeName: 'Company',
      TypeNamePlural: 'Companies',
      Description: {Value: ID}
    },
    // facet for the person table
    HeaderFacets: [
      {$Type: 'UI.ReferenceFacet', Target: 'Person/@UI.LineItem'}
    ]

);

annotate Admin.Person with @(
  // person table (only displayed in detail view) with columns
  UI.LineItem: [
    {$Type: 'UI.DataField', Value: 'comp/cName'},
    {$Type: 'UI.DataField', Value: 'pName'}
  ]);

It might be that the code above doesn't work right away because I didn't test it. But I created a working example with the Northwind OData V2 Service using the customer entity for the list view and the order entity in a table in the detail view. You can recreate the example by running the Fiori List Report Object Page wizard with the OData service URL https://services.odata.org/Northwind/Northwind.svc/ and the main entity Customer. When the generation of the project is finished you can replace the content of the annotation.xml with the following:

<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
    <edmx:Reference Uri="https://sap.github.io/odata-vocabularies/vocabularies/Common.xml">
        <edmx:Include Namespace="com.sap.vocabularies.Common.v1" Alias="Common" />
    </edmx:Reference>
    <edmx:Reference Uri="https://sap.github.io/odata-vocabularies/vocabularies/UI.xml">
        <edmx:Include Namespace="com.sap.vocabularies.UI.v1" Alias="UI" />
    </edmx:Reference>
    <edmx:Reference Uri="https://sap.github.io/odata-vocabularies/vocabularies/Communication.xml">
        <edmx:Include Namespace="com.sap.vocabularies.Communication.v1" Alias="Communication" />
    </edmx:Reference>
    <edmx:Reference Uri="/Northwind/Northwind.svc/$metadata">
        <edmx:Include Namespace="NorthwindModel" />
        <edmx:Include Namespace="ODataWebV3.Northwind.Model" />
    </edmx:Reference>
    <edmx:DataServices>
        <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="local">
            <Annotations Target="NorthwindModel.Customer">
                <Annotation Term="UI.LineItem">
                    <Collection>
                        <Record Type="UI.DataField">
                            <PropertyValue Property="Value" Path="CompanyName" />
                        </Record>
                    </Collection>
                </Annotation>
                <Annotation Term="UI.Facets">
                    <Collection>
                        <Record Type="UI.ReferenceFacet">
                            <PropertyValue Property="Target" AnnotationPath="Orders/@UI.LineItem" />
                        </Record>
                    </Collection>
                </Annotation>
            </Annotations>
            <Annotations Target="NorthwindModel.Order">
                <Annotation Term="UI.LineItem">
                    <Collection>
                        <Record Type="UI.DataField">
                            <PropertyValue Property="Value" Path="OrderID" />
                        </Record>
                        <Record Type="UI.DataField">
                            <PropertyValue Property="Value" Path="Customer/CompanyName" />
                        </Record>
                    </Collection>
                </Annotation>
            </Annotations>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>

I hope this solves your problem. If you have any questions feel free to ask.