Skip to Content
Product Information

Enabling Product Data Collaboration on BOMs: Creating BOM Service with Annotations

The Shared Product Data Feature of SAP S/4 HANA Cloud for intelligent product design provides the ability to collaborate on objects from the On-Premise system and allows authorized users to search and import these objects into the collaboration and publish it.

The blog explains the mechanism to describe the structure of the UI for the object Bill of Material imported from S/4HANA system in IPD. We use OData to describe the model and the way to describe anything in such modern OData interfaces is Annotations. We leverage the annotations that are already residing in all the S/4 HANA object maintenance fiori applications.

I. Create Gateway Project

  1. To develop a service using SAP Gateway Service Builder, you need to create a project of type   “Service with Vocabulary-Based Annotations
  2. Create a New Project by clicking on the   icon in top left corner.
  3. In edit mode, right click on the Data Model and choose to redefine service.with redefine options (OData Service SAP GW ).

II. Defining the Data Model

In Select Service region:

  1. In Technical Service Name field enter technical name of the service as “API_BILL_OF_MATERIAL_SRV . You can select only those services that are registered in the current SAP Business Suite back-end system.Alternatively, you can use input help available for this field.
  2. In Version field specify the version of the service. On selecting the service from input help version automatically populates.
  3. Once you select a service, the model displays in tree view, allowing you to select the required artifacts (entity types, associations,) for new model.Select relevant entity types and associations as shown in the snapshot
    1. A_BillOfMaterialType
    2. A_BillOfMaterialItemType

III. Vocabulary Import in the Data Model

From the Vocabulary  Repository, you can import vocabularies into the service builder to annotate the data model artifacts.

  1. In the edit mode, right click on the Data Model, choose Import->Vocabulary in the resulting menu the Vocabulary Repository window appears.
  2. Select the vocabulary com.sap.vocabularies.UI.v1 and click continue.
  3. In the Tree view a new folder with the name Vocabularies will be created under the Data Model and the vocabularies imported into this folder.
  4. Double click on the Terms node under the Vocabularies folder to see the details of the imported annotations in the mass maintenance view.

IV. Add Vocabulary-Based Annotations

  1. Once the vocabulary definitions are added to the data model, the terms from the vocabulary definition can be used to annotate the service.
  2. Double-click the sub folder that contains the artifacts you want to annotate, for example, Entity Types. Existing entity types are listed in the mass maintenance view.

Annotations SelectionFields

  • For Root Entity type A_BillOfMaterialType define SelectionFields as collection of values
  • Push create button to create values under Annotation Data and pass SelectionFields as Expression Value

Annotations HeaderInfo

  • For HeaderInfo Annotation Term define PropertyValue Property attributes with the following attribute-values:
  • TypeName: the label to use for the object type.
  • TypeNamePlural: the label to use for the plural of the object type.
  • Title: the mapping between the object title field and the external OData source.

Annotations Identification

  • Each row of the Identification section should be described as a Record entry within an annotation Collection.
  • The row label and field bindings are described by the “Label” and “Value” properties in each Record.

Annotations Facets

  • Add reference facets to facets collection. Each record refers an association
  • Maintain label and target properties
  • The target property should have syntax: <nav-prop>/@com.sap.vocabularies.UI.v1.LineItem

Annotations FieldGroup

  • Maintain field group label
  • Add data fields to Data collection
  • Maintain fields to be displayed in the field group as value properties

V. Generate Runtime Artifacts

  1. Select the service and click on Generate button
  2. Continue on the subsequent Dialog to Generate the Classes
  3. The newly generated artifacts can be seen in the Runtime Artifacts folder.

VI. Adding LineItem annotations and setting UI field         importance in MPC EXT

  • Open the Metadata Provider Class Extension
  • Redefine “DEFINE _VOCAB_ANNOTATIONS” Method.
  • Set UI field importance for each DataField as shown.
  • method DEFINE_VOCAB_ANNOTATIONS.
        TRY.
            CALL METHOD super->define_vocab_annotations.
    *       Set UI.Importance to high for all line items
            DATA: lo_ann_target TYPE REF TO /iwbep/if_mgw_vocan_ann_target.   " Vocabulary Annotation Target                     "#EC NEEDED
            DATA: lo_annotation TYPE REF TO /iwbep/if_mgw_vocan_annotation.   " Vocabulary Annotation                            "#EC NEEDED
            DATA: lo_collection TYPE REF TO /iwbep/if_mgw_vocan_collection.   " Vocabulary Annotation Collection                 "#EC NEEDED
            DATA: lo_function   TYPE REF TO /iwbep/if_mgw_vocan_function.     " Vocabulary Annotation Function                   "#EC NEEDED
            DATA: lo_fun_param  TYPE REF TO /iwbep/if_mgw_vocan_fun_param.    " Vocabulary Annotation Function Parameter         "#EC NEEDED
            DATA: lo_property   TYPE REF TO /iwbep/if_mgw_vocan_property.     " Vocabulary Annotation Property                   "#EC NEEDED
            DATA: lo_record     TYPE REF TO /iwbep/if_mgw_vocan_record.       " Vocabulary Annotation Record                     "#EC NEEDED
            DATA: lo_simp_value TYPE REF TO /iwbep/if_mgw_vocan_simple_val.   " Vocabulary Annotation Simple Value               "#EC NEEDED
            DATA: lo_url        TYPE REF TO /iwbep/if_mgw_vocan_url.          " Vocabulary Annotation URL                        "#EC NEEDED
            DATA: lo_label_elem TYPE REF TO /iwbep/if_mgw_vocan_label_elem.   " Vocabulary Annotation Labeled Element            "#EC NEEDED
    
            lo_ann_target = vocab_anno_model->create_annotations_target( 'A_BillOfMaterialType' ). "#EC NOTEXT
            lo_ann_target->set_namespace_qualifier( 'API_BILL_OF_MATERIAL_SRV' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'Material' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'Plant' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'BillOfMaterialVariantUsage' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'BillOfMaterialVariant' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'HeaderValidityStartDate' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'HeaderValidityEndDate' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'EngineeringChangeDocument' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_ann_target = vocab_anno_model->create_annotations_target( 'A_BillOfMaterialItemType' ). "#EC NOTEXT
            lo_ann_target->set_namespace_qualifier( 'API_BILL_OF_MATERIAL_SRV' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'BillOfMaterialItemNumber' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'BillOfMaterialItemCategory' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'BillOfMaterialComponent' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'BOMItemDescription' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'BillOfMaterialItemQuantity' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'BillOfMaterialItemUnit' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'ValidityStartDate' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'ValidityEndDate' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'EngineeringChangeDocument' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
            lo_annotation = lo_ann_target->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.LineItem' ). "#EC NOTEXT
            lo_collection = lo_annotation->create_collection( ).
            lo_record = lo_collection->create_record( iv_record_type = 'com.sap.vocabularies.UI.v1.DataField' ). "#EC NOTEXT
            lo_property = lo_record->create_property( 'Value' ). "#EC NOTEXT
            lo_simp_value = lo_property->create_simple_value( ).
            lo_simp_value->set_path( 'IsAssembly' ). "#EC NOTEXT
            lo_annotation = lo_record->create_annotation( iv_term = 'com.sap.vocabularies.UI.v1.Importance' ).
            lo_simp_value = lo_annotation->create_simple_value( ).
            lo_simp_value->set_enum_member_by_name( 'com.sap.vocabularies.UI.v1.ImportanceType/High' ). "#EC NOTEXT
          CATCH /iwbep/cx_mgw_med_exception .
        ENDTRY.
    endmethod.

VII. Registration and Activation of the Generated Service

  1. Go to Service maintenance and choose to Register
  2. Choose Package and continue
  3. Successful Registration of the service can be seen in the Status

 

The metadata-based annotation can be generated and respective info can be used to map it to the dynamic UI.

Conclusion

The intent of this blog is to summarize how we can create a service on top of any service delivered in SAP API hub and how annotation can be modeled on top of the standard service. In the next blog we will be explaining how the generated or activated service in ABAP through gateway builder can be visualized in shared product UI and it’s consumption.

 

References

  1. Product Data eXchange with SAP S/4HANA Cloud for intelligent product design
  2. Introduction to Annotations & Vocabularies
  3. Introduction to Annotation Tags and Properties
  4. Annotation’s usage in S4/HANA Intelligent product design
Be the first to leave a comment
You must be Logged on to comment or reply to a post.