Friday 22 March 2019

Creating a draft enabled Sales Order Fiori App using the new ABAP Programming Model – Part 3: Defining the UI & Creating the Fiori Elements App

Defining the UI using Metadata Extensions


In the previous part we’ve defined the data model for our app. Now it’s time to define how our app should look like. We’ll do this by adding UI annotations to our consumption views using Metadata Extensions.

Within the next few subsections I’ll try to explain how the different annotations determine how the UI will look like.

UI annotations for List Report

Annotation Usage
@UI.typeNamePlural Title above the list
@UI.selectionField  Default position of the field within the selection criteria 
@UI.lineItem  Default position of the field within the table 

ABAP Development, SAP Fiori for SAP S/4HANA, SAP S/4HANA, SAP SD, SAP ABAP Certifications

UI annotations for Object Page facets

Annotation Usage 
@UI.facet  Used to group fields as desired
@UI.facet.type  Type of facet (CollectionFacet, ReferenceFacet or ReferenceURLFacet) 
@UI.facet.label  Description (title) for facet 
@UI.facet.parentId   Reference to parent facet (for nested facets) 
ABAP Development, SAP Fiori for SAP S/4HANA, SAP S/4HANA, SAP SD, SAP ABAP Certifications

ABAP Development, SAP Fiori for SAP S/4HANA, SAP S/4HANA, SAP SD, SAP ABAP Certifications

Sales Order Header consumption view Metadata Extension

@Metadata.layer: #CUSTOMER

@UI: {
    headerInfo: {
    typeName: 'Sales Order',
    typeNamePlural: 'Sales Orders',
    title: { type: #STANDARD, label: 'Sales Order' }
    }
}

annotate view ZSD_C_SOHEADER
    with 
{
    @UI.facet: [
        { 
            label: 'Header data',
            id: 'Header',
            type: #COLLECTION
        },
        {
            label: 'Document Information',
            id : 'HeaderData',
            parentId : 'Header',
            type : #FIELDGROUP_REFERENCE,
            targetQualifier : 'HeaderData'
        },
        {
            label: 'Organizational Information',
            id : 'OrgInfo',
            parentId : 'Header',
            type : #FIELDGROUP_REFERENCE,
            targetQualifier : 'OrgInfo'
        },
        {
            label: 'Customer Information',
            id : 'CustomerInfo',
            parentId : 'Header',
            type : #FIELDGROUP_REFERENCE,
            targetQualifier : 'CustomerInfo'
        },
        {
            label: 'Internal Information',
            id : 'InternalInfo',
            parentId : 'Header',
            type : #FIELDGROUP_REFERENCE,
            targetQualifier : 'InternalInfo'
        },
        {
            label: 'Items',
            purpose: #STANDARD,
            id: 'Items',
            type: #LINEITEM_REFERENCE,
            targetElement: '_items'
            
        }
        
    ]
    
    @UI: {
      lineItem: [ { position: 10, label: 'Sales Order', importance: #HIGH } ],
      selectionField: [ { position: 10 } ],
      identification:[ { position: 10, label: 'Sales Order' } ],
      fieldGroup: [{ qualifier: 'HeaderData', position: 10 }]
    }
    orderNumber; 
    @UI: {
      lineItem: [ { position: 20, label: 'Order Type', importance: #HIGH } ],
      selectionField: [ { position: 20 } ],
      identification:[ { position: 20, label: 'Order Type' } ],
      fieldGroup: [{ qualifier: 'HeaderData', position: 20 }]
    }
    orderType;
    @UI: {
      lineItem: [ { position: 110, label: 'Net Value', importance: #HIGH } ],
      selectionField: [ { position: 150 } ],
      identification:[ { position: 150, label: 'Net Value' } ],
      fieldGroup: [{ qualifier: 'HeaderData', position: 30 }]
    } 
    netValue; 
    @UI: {
      selectionField: [ { position: 160 } ],
      identification:[ { position: 160, label: 'Currency' } ]
    } 
    currency;   
    @UI: {
      lineItem: [ { position: 30, label: 'Sales Organization', importance: #HIGH } ],
      selectionField: [ { position: 30 } ],
      identification:[ { position: 30, label: 'Sales Organization' } ],
      fieldGroup: [{ qualifier: 'OrgInfo', position: 10 }]
    }
    salesOrganization;
    @UI: {
      selectionField: [ { position: 40 } ],
      identification:[ { position: 40, label: 'Distribution Channel' } ],
      fieldGroup: [{ qualifier: 'OrgInfo', position: 20 }]
    } 
    distributionChannel; 
    @UI: {
      selectionField: [ { position: 50 } ],
      identification:[ { position: 50, label: 'Division' } ],
      fieldGroup: [{ qualifier: 'OrgInfo', position: 30 }]
    } 
    division;
    @UI: {
      selectionField: [ { position: 60 } ],
      identification:[ { position: 60, label: 'Sales Office' } ],
      fieldGroup: [{ qualifier: 'OrgInfo', position: 40 }]
    } 
    salesOffice; 
    @UI: {
      selectionField: [ { position: 70 } ],
      identification:[ { position: 70, label: 'Sales Group' } ],
      fieldGroup: [{ qualifier: 'OrgInfo', position: 50 }]
    } 
    salesGroup; 
    @UI: {
      lineItem: [ { position: 80, label: 'Sold-to', importance: #HIGH } ],
      selectionField: [ { position: 80 } ],
      identification:[ { position: 80, label: 'Sold-to' } ],
      fieldGroup: [{ qualifier: 'CustomerInfo', position: 10 }]
    } 
    soldTo;
    @UI: {
      lineItem: [ { position: 90, label: 'Ship-to', importance: #HIGH } ],
      selectionField: [ { position: 90 } ],
      identification:[ { position: 90, label: 'Ship-to' } ],
      fieldGroup: [{ qualifier: 'CustomerInfo', position: 20 }]
    } 
    shipTo; 
    @UI: {
      lineItem: [ { position: 100, label: 'Customer Reference', importance: #LOW } ],
      selectionField: [ { position: 100 } ],
      identification:[ { position: 100, label: 'Customer Reference' } ],
      fieldGroup: [{ qualifier: 'CustomerInfo', position: 30 }]
    } 
    customerReference;
    
    @UI: {
      lineItem: [ { position: 130, label: 'Created By', importance: #LOW } ],
      selectionField: [ { position: 110 } ],
      identification:[ { position: 110, label: 'Created By' } ],
      fieldGroup: [{ qualifier: 'InternalInfo', position: 10 }]
    } 
    createdBy;
    @UI: {
      lineItem: [ { position: 140, label: 'Created On', importance: #LOW } ],
      selectionField: [ { position: 120 } ],
      identification:[ { position: 120, label: 'Created On' } ],
      fieldGroup: [{ qualifier: 'InternalInfo', position: 20 }]
    }  
    createdOn;
    @UI: {
      selectionField: [ { position: 130 } ],
      identification:[ { position: 130, label: 'Created At' } ],
      fieldGroup: [{ qualifier: 'InternalInfo', position: 30 }]
    }  
    createdAt; 
    @UI: {
      selectionField: [ { position: 140 } ],
      identification:[ { position: 140, label: 'Changed On' } ],
      fieldGroup: [{ qualifier: 'InternalInfo', position: 40 }]
    } 
    changedOn; 
}

Sales Order Item consumption view Metadata Extension

@Metadata.layer: #CUSTOMER

@UI: {
    headerInfo: {
    typeName: 'Sales Order Item',
    typeNamePlural: 'Sales Order Items',
    
    title: { type: #STANDARD, label: 'Sales Order Item' }
    }
}

annotate view ZSD_C_SOITEM
    with 
{
    @UI.facet: [
        {
            label: 'Item Information',
            id : 'ItemData',
            //parentId : 'Header',
            type : #FIELDGROUP_REFERENCE,
            targetQualifier : 'ItemData'
        },
        {
            label: 'Internal Information',
            id : 'InternalInfo',
            //parentId : 'Header',
            type : #FIELDGROUP_REFERENCE,
            targetQualifier : 'InternalInfo'
        }
    ]

    @UI: {
      hidden: true,
      lineItem: [ { position: 10, label: 'Sales Order', importance: #HIGH } ],
      selectionField: [ { position: 10 } ],
      identification:[ { position: 10, label: 'Sales Order' } ],
      fieldGroup: [{ qualifier: 'ItemData', position: 10 }]
    } 
    orderNumber;
    @UI: {
      lineItem: [ { position: 20, label: 'Item', importance: #HIGH } ],
      selectionField: [ { position: 20 } ],
      identification:[ { position: 20, label: 'Item' } ],
      fieldGroup: [{ qualifier: 'ItemData', position: 20 }]
    } 
    orderItem; 
    @UI: {
      lineItem: [ { position: 30, label: 'Material', importance: #HIGH } ],
      selectionField: [ { position: 30 } ],
      identification:[ { position: 30, label: 'Material' } ],
      fieldGroup: [{ qualifier: 'ItemData', position: 30 }]
    } 
    material;
    @UI: {
      lineItem: [ { position: 40, label: 'Description', importance: #HIGH } ],
      selectionField: [ { position: 40 } ],
      identification:[ { position: 40, label: 'Description' } ],
      fieldGroup: [{ qualifier: 'ItemData', position: 40 }]
    }  
    itemDescription; 
    @UI: {
      lineItem: [ { position: 50, label: 'Quantity', importance: #HIGH } ],
      selectionField: [ { position: 50 } ],
      identification:[ { position: 50, label: 'Quantity' } ],
      fieldGroup: [{ qualifier: 'ItemData', position: 50 }]
    } 
    orderQuantity;
    @UI: {
      selectionField: [ { position: 60 } ],
      identification:[ { position: 60, label: 'Sales Unit' } ]
    }  
    salesUnit;
    @UI: {
      lineItem: [ { position: 70, label: 'Net Value', importance: #HIGH } ],
      selectionField: [ { position: 70 } ],
      identification:[ { position: 70, label: 'Net Value' } ],
      fieldGroup: [{ qualifier: 'ItemData', position: 70 }]
    }  
    netValue; 
    @UI: {
      selectionField: [ { position: 80 } ],
      identification:[ { position: 80, label: 'Currency' } ]
    } 
    currency; 
    @UI: {
      lineItem: [ { position: 90, label: 'Created By', importance: #LOW } ],
      selectionField: [ { position: 90 } ],
      identification:[ { position: 90, label: 'Created By' } ],
      fieldGroup: [{ qualifier: 'InternalInfo', position: 10 }]
    } 
    createdBy;
    @UI: {
      lineItem: [ { position: 100, label: 'Created On', importance: #LOW } ],
      selectionField: [ { position: 100 } ],
      identification:[ { position: 100, label: 'Created On' } ],
      fieldGroup: [{ qualifier: 'InternalInfo', position: 20 }]
    } 
    createdOn;
    @UI: {
      lineItem: [ { position: 110, label: 'Created At', importance: #LOW } ],
      selectionField: [ { position: 110 } ],
      identification:[ { position: 110, label: 'Created At' } ],
      fieldGroup: [{ qualifier: 'InternalInfo', position: 30 }]
    } 
    createdAt;
    @UI: {
      lineItem: [ { position: 120, label: 'Changed On', importance: #LOW } ],
      selectionField: [ { position: 120 } ],
      identification:[ { position: 120, label: 'Changed On' } ],
      fieldGroup: [{ qualifier: 'InternalInfo', position: 40 }]
    } 
    changedOn; 
}

Exposing the Business Object consumption CDS view as oData service


Open transaction /IWFND/MAINT_SERVICE and add the generated service to the list of activated services. This can either be co-deployed or routing-based, depending on your system setup.

ABAP Development, SAP Fiori for SAP S/4HANA, SAP S/4HANA, SAP SD, SAP ABAP Certifications

Generating the Fiori Elements App


Open up SAP Web IDE and create a new project from template. Choose for “List Report Application” and click Next.

ABAP Development, SAP Fiori for SAP S/4HANA, SAP S/4HANA, SAP SD, SAP ABAP Certifications

Enter following details (you can choose your own):

◈ Project Name: ZSD_SO_DEMO_V1
◈ Title: Manage Sales Orders
◈ Namespace: be.thevaluechain
◈ Description: Manage Sales Orders

Click “Next”

ABAP Development, SAP Fiori for SAP S/4HANA, SAP S/4HANA, SAP SD, SAP ABAP Certifications

In the next screen choose your desired backend system from the service catalog and select your previously activated oData service. Click “Next“.

ABAP Development, SAP Fiori for SAP S/4HANA, SAP S/4HANA, SAP SD, SAP ABAP Certifications

Select all remote annotations and click “Next“.

ABAP Development, SAP Fiori for SAP S/4HANA, SAP S/4HANA, SAP SD, SAP ABAP Certifications

Enter following details:

◈ OData Collection: ZSD_C_SOHEADER
◈ OData Navigation: to_items

Click “Finish“.

ABAP Development, SAP Fiori for SAP S/4HANA, SAP S/4HANA, SAP SD, SAP ABAP Certifications

Select the newly created project and click the “play” button in the toolbar.

ABAP Development, SAP Fiori for SAP S/4HANA, SAP S/4HANA, SAP SD, SAP ABAP Certifications

Select “flpSandbox.html” and click “OK“.

ABAP Development, SAP Fiori for SAP S/4HANA, SAP S/4HANA, SAP SD, SAP ABAP Certifications

Open the app by clicking the generated tile.

ABAP Development, SAP Fiori for SAP S/4HANA, SAP S/4HANA, SAP SD, SAP ABAP Certifications

Result:

ABAP Development, SAP Fiori for SAP S/4HANA, SAP S/4HANA, SAP SD, SAP ABAP Certifications

Our app now has basic functionality:

◈ Search
◈ Result list report
◈ Search helps
◈ Detail screens (display)

No comments:

Post a Comment