제품 개요 이해
    설치, 배포 및 설정 수행
    Out-of the Box 모바일 앱의 구성 수행
    어플리케이션 확장성 사용
    클라이언트 디버깅 및 브랜딩 수행
    근본 원인 분석 및 성능 최적화 수행
    업그레이드 및 지원 설명
    부록을 통해 트롤링

    Performing Advanced Extensions

    Objective

    After completing this lesson, you will be able to perform Advanced Extensions

    Explaining an OData Mobile Data Object

    An OData mobile data object (also known as OMDO) provides business logic for a business object used in an OData-based mobile application. An OMDO provides both technical implementation and configuration support for the represented business object, including all aspects of related operations such as object creation, update, deletion, or read and downloading. The OMDO also supports configurations such as data distribution rules for data download.

    OData requests for a business object are mapped to an OMDO object. The OMDO handler then processes the requests for the OMDO object.

    • For read requests, the OMDO handler considers and enforces the data distribution rules and other configuration settings and determines the proper output response.

    • For create, update, and delete requests, the OMDO handler creates or updates the SAP BusinessObjects in the back-end system as requested in the OData requests, and provides the relevant response.

    As mentioned in the Unit-2 of this Training handbook, an ABAP OO class handler is assigned to an OMDO and provides the technical implementation for the OMDO object. The OMDO handler must be a subclass of /MFND/CL_CORE_OMDO_HNDLER_BASE.

    The Process Flow of the OMDO determines how the OMDO handler processes OData entity set read requests. Based on the process flow setting, different OMDO handler methods are invoked at runtime. The OMDO handler determines which process flow it supports.

    • Basic Flow without Key List: Typically used by the OMDO handler to support simple SAP BusinessObjects with a single entity type and no change detection support. In general, suitable for SAP Configuration Data.

      Examples of SAP BusinessObjects that use the basic flow without key list include customizing data, such as plant or order type. OMDO handlers that only support basic flow are typically subclasses from /MFND/CL_CORE_OMDO_BASIC_HNDLR.

    • Standard Flow using Key List: Typically used by the OMDO handler to support complex SAP BusinessObjects with multiple entity types, complex relationships between entity types and data distribution rules, and with change detection support. In general, suitable for SAP Master and Transactional Data.

      Examples of SAP BusinessObjects that use the standard flow include transaction data objects such as work orders or notifications; and leading data objects such as equipment or functional locations.

    As part of this training, we create:

    • Purchase Organization–Basic Flow

    • Purchase Requisition–Standard Flow

    Extend SSAM by Creating a new Entity (Purchase Organization)

    Business Scenario

    In this exercise, we add a new EntitySet (PurchaseOrganizations) in the backend. This EntitySet is used as a list picker on the client.

    You follow these high-level steps for creating a new entity:

    Steps to configure an oData Mobile Data Object (oMDO). It includes steps for development, object configuration, model configuration, persona assignment, and testing the service.
    1. Development Tasks (SAP GUI - ABAP Workbench and Dictionary).
      1. Reuse the structure (/SYCLO/MM_PURCHASEORG_STR).
      2. Create oMDO Class Handler for Fetching the Purchase Organizations.
    2. oMDO Object Configuration Tasks (/SYCLO/CONFIGPANEL).

      Assign oMDO Class.

    3. oMDO Model Configuration.
      1. Create Entity & Entity set.
      2. Assign Entity to oMDO Object (create in step 2a).
      3. Configure Associations.
      4. Configure Navigation.
    4. Assign oMDO to Feature and Persona.
      1. Assign oMDO to Feature.
      2. Assign Feature to Persona.
    5. Test using the Gateway Client.
    6. In SAP BAS, perform the Sync Service to update the Metadata.

    Note

    Use transaction SE24 and there the reference class handler /MERP/CL_MM_PURCHSE_ORG_OD to create your copy Zxxx files. The code snippets provided in this handbook are examples for your reference only. Copy the required coding from the reference class.

    Note

    The steps below are giving a guide so that you can perform this exercise in your own system landscape.

    Task 1: Perform Development Tasks–Create oMDO Class Handler

    Steps

    1. Create an oMDO Class for fetching Purchase Order data from SAP with the following data:

      FieldValue
      DescriptionPurchase Organization OMDO Handler for IAM_##
      Instance GenerationPublic
      Usual ABAP ClassSelect the radio button.
      FinalUncheck the checkbox.
      1. Log in to the SAP system and navigate to transaction code SE24.

      2. Enter ZIAM_##_CL_MM_PURCHASE_ORG_OD.

      3. Choose the Create button.

      4. In the pop-up window, choose (the default) Object Type Class radio button.

      5. Choose the Enter button.

      6. Enter the details as given in the table.

      7. Select the Save button.

      8. On the next pop-up window, choose the Local Object button.

    2. Set the super class of this class to /MFND/CL_CORE_OMDO_BASIC_HNDLR.

      1. Once you are in the class, choose the Properties tab.

      2. Choose the Superclass button.

      3. Enter /MFND/CL_CORE_OMDO_BASIC_HNDLR in the superclass name.

      4. Verify that the Final check box is unchecked.

      5. Choose the Save button.

        At this point, you notice that there are few interfaces and method loaded in the corresponding tabs.

        Note

        Set up your environment for better legibility by choosing in the menu bar UtilitiesSettingsClass Builder tab, check the Display Aliases and Group by Interfaces and Superclasses and choose Enter.

    3. Add Object Types.

      Use the following data:

      FieldAttribute1
      TypeGTYP_DOF_FILTER_VALS_STR
      VisibilityPublic
      Typing<keep the initial value> TYPE
      Associated Type 
      DescriptionPurchase Requisition Filters config panel

      1. Choose the Types tab.

      2. Enter the data as given in the preceding tables.

      3. Choose the Direct Type Entry button .

      4. If prompted, choose Save changes.

      5. In the protected sectionenter the following code.

        Code Snippet
        123456789101112
        types: BEGIN OF gtyp_dof_filter_vals_str, purch_org TYPE REF TO /mfnd/core_range_tab, comp_code TYPE REF TO /mfnd/core_range_tab, END OF gtyp_dof_filter_vals_str . data STR_DOF_FILTER_VALS type GTYP_DOF_FILTER_VALS_STR .
      6. Save the changes.

    4. Add two attributes to your class.

      Use the following details for the new Attribute: CONST_PURCHASEORG_ENTITY:

      LevelVisibilityAssociated TypeDescriptionInitial Value
      ConstantPublic/MFND/CORE_TECH_ENTITY_TYP_DTEoMDO - Technical Entity Type'PURCHASEORG'

      Use the following details for the new Attribute: STR_DOF_FILTER_VALS:

      LevelVisibilityAssociated TypeDescriptionInitial Value
      Instance AttributeProtectedGTYP_DOF_FILTER_VALS_STRoMDO–Purchase Org Filter 

      Note

      Single quotes are required for the Initial Value 'PURCHASEORG.'

      1. Choose the Attributes tab.

      2. Enter the values as given in the preceding table.

    5. Redefine the method DEFINE_BO_ENTITY_MODEL with the following code:

      Code Snippet
      1234567
      method /MFND/IF_CORE_OMDO_BO_MODEL~DEFINE_BO_ENTITY_MODEL. CLEAR et_bo_entities. et_bo_entities = VALUE #( ( tech_entity_type = me->const_purchaseorg_entity ref_struct = '/MERP/MM_PURCHASEORG_ENTY_STR' flag_lead_entity = abap_true ) ). endmethod.
      1. Choose the Methods tab.

      2. Choose the find button and search for the method DEFINE_BO_ENTITY_MODEL.

      3. Choose the Redefine button.

      4. Clear the code within the method and copy and paste the given code to the method.

      5. Check syntax (Ctrl + F2).

      6. Choose Save.

    6. Redefine the method GET_DATA_FOR_READ_REQUEST with the following code:

      Code Snippet
      1234567891011121314151617181920212223242526
      method GET_DATA_FOR_READ_REQUEST. DATA: lt_purchaseorg_data TYPE STANDARD TABLE OF /SYCLO/MM_PURCHASEORG_STR. *---Main Section GET REFERENCE OF lt_purchaseorg_data INTO DATA(lref_purchaseorg_data). map_filter_values_to_structure( EXPORTING iv_operation = const_omdo_core_op_read CHANGING cs_filters = str_dof_filter_vals ). DATA(lv_select_clause) = me->build_oper_field_select_string( iv_tabname = 'T024E' ). SELECT (lv_select_clause) FROM t024e INTO CORRESPONDING FIELDS OF TABLE lt_purchaseorg_data WHERE ekorg IN str_dof_filter_vals-purch_org->* AND bukrs IN str_dof_filter_vals-comp_code->*. cref_omdo_data->add_omdo_output_single( iv_tech_entity_type = is_entity_input_info-tech_entity_type iv_request_no = is_entity_input_info-request_no iref_data = lref_purchaseorg_data ). endmethod.
      1. Choose Back to return to the Methods tab.

      2. Locate the GET_DATA_FOR_READ_REQUEST.

      3. Choose Redefine Method from the tool bar.

      4. Clear the code within the method and copy paste the given code in method.

      5. Check syntax (Ctrl + F2).

      6. Choose Save.

    7. Redefine the method GET_OPER_FIELD_CATALOG_TABLES with the following code:

      Code Snippet
      123456789101112131415161718192021
      method /MFND/IF_CORE_OMDO_FIELD_CAT~GET_OPER_FIELD_CATALOG_TABLES. super->get_oper_field_catalog_tables( IMPORTING et_field_catalog_tables = et_field_catalog_tables et_exclusion_field_list = et_exclusion_field_list et_required_field_list = et_required_field_list ). et_field_catalog_tables = VALUE #( ( omdo_handler = me->clsname operation = const_omdo_core_op_read tabname = 'T024E' ) ). et_required_field_list = VALUE #( ( omdo_handler = me->clsname operation = const_omdo_core_op_read tabname = 'T024E' fieldname = 'EKORG' ) ( omdo_handler = me->clsname operation = const_omdo_core_op_read tabname = 'T024E' fieldname = 'EKOTX' ) ). endmethod.
      1. Choose Back to return to the Methods tab.

      2. Locate the GET_OPER_FIELD_CATALOG_TABLES

      3. Choose Redefine Method from the tool bar.

      4. Clear the code within the method and copy paste the given code in method.

      5. Check syntax (Ctrl + F2).

      6. Choose Save.

    8. Redefine the method GET_DATA_FILTER_LIST with the following code:

      Code Snippet
      1234567891011121314151617181920
      method /MFND/IF_CORE_OMDO_FILTER_SERV~GET_DATA_FILTER_LIST. REFRESH et_data_filters. et_data_filters = VALUE #( ( dof_name = 'PURCH_ORG' usage_tabname = 'T024E' usage_fieldname = 'EKORG' dof_group = /smfnd/cl_core_std_mdo_dofgrp=>std_dofgrp_distrmod omdo_handler = me->clsname operation = me->const_omdo_core_op_read ) ( dof_name = 'COMP_CODE' usage_tabname = 'T024E' usage_fieldname = 'BUKRS' dof_group = /smfnd/cl_core_std_mdo_dofgrp=>std_dofgrp_distrmod omdo_handler = me->clsname operation = me->const_omdo_core_op_read ) ). endmethod.
      1. Choose Back to return to the Methods tab.

      2. Locate the GET_DATA_FILTER_LIST.

      3. Choose Redefine Method from the tool bar.

      4. Clear the code within the method and copy paste the given code in method.

      5. Check syntax (Ctrl + F2).

      6. Choose Save.

    9. Activate the class.

      1. Go back to the class builder and Activate the entire class.

      2. Choose the Activate button (Ctrl+F3) and choose Enter on the pop-up window.

      3. Save as a local object.

        You should have coded four methods and defined two attributes.

        In the Methods tab, four methods are shown and two attributes are defined.

    Task 2: Perform oMDO Object Configuration

    Note

    For the training, a mobile application (ZIAM_##_SERVICE_ASSET_MANAGER) is already created by copying a standard mobile app.

    Note that the custom App is only for training purposes, in a project implementation you will directly work with the standard Mobile App.

    This task involves the configuration of the oMDO Object. This includes configuration for data extraction and distribution logic. It determines the runtime behavior of the class created in the previous step.

    Steps

    1. Create a new oMDO Object using the following details for your Mobile Application ZIAM-##.

      FieldValueExplanation
      oMDO IDZIAM150_##_PURCHASE_ORG 
      DescriptionZIAM150_## - Purchase Organization 
      Mobile ApplicationZIAM-## 
      oMDO HandlerZIAM_##_CL_MM_PURCHASE_ORG_OD (class created in previous task) 
      Process FlowBasic Process Flow without Key ListDecided based on the super class /MFND/CL_CORE_OMDO_BASIC_HNDLR
      Exempt Read Entity RequestNot Checked (false) 
      Enable Client State Tracking.CheckedTracks data downloaded to the device. Keys are compared during the next sync.
      Enable periodic refresh.Checked 
      Refresh frequency.720 
      Refresh on User Change.Not checkedApplicable for device sharing scenario. The data remains the same for multiple users as long as the user parameter for plant and company code are the same.
      Optimal Client State ReuseCheckedApplicable if "Enable Client State Tracking" is set to True. If there is no change in data, it skips the update of the client state keys in the DB and updates a counter.
      Sync Session Max Idle Time120Estimated maximum duration of sync for the oMDO
      Sync Priority.1

      Represents the processing sequence for read requests in a batch.

      For config data (with no dependency) we generally configure it as "1" and include in the first batch in Offline Access INI file.

      If the Entity has a dependency, ensure the number is higher than the source entity.

      1. Log in to the SAP GUI.

      2. Enter /n/syclo/configpanel to launch the ConfigPanel.

      3. Once you are within the Config Panel (Web Dynpro opens in Browser), choose oData Mobile Data Object Configuration in the oData Channel Integration settings section.

      4. Next, use the Mobile Application Filter dropdown to choose your mobile application IAM150-## (ZIAM_##_ASSET_MANAGER). It is important that you choose the correct mobile app name.

        The General Setting tab is selected.
      5. Select the mobile app and expand control on the left-hand side to view the oData Mobile data objects (oMDOs).

      6. Choose the Create button to create a new oMDO Object using the data given in the preceding table.

      7. Choose the Technical Model Info tab to view the technical entities exposed from oMDO Class Handler DEFINE_BO_ENTITY_MODEL.

      8. Choose the Data Filter and check the filters. Initially do not configure the filters, however once you have it working. You can configure the COMPANY_CODE filter and explore options using static and user parameter filters.

      9. Choose the Field Selection and choose the EKORG, EKOTX, BUKRS fields.

        The Field Selection tab is selected.
    2. Save your changes and assign them to a request.

      1. Choose the Save button to save the changes.

      2. If you have already created a customizing request, assign this and go to the next task.

      3. If you have not created a customizing request in an earlier exercise, in the pop-up window choose Create Request to capture the configuration changes into a transport.

      4. Provide a short description (IAM150-## config changes) in pop-up window.

      5. Choose the Create button.

      6. Once the Change Request Number is copied back to the pop-up, choose the Continue button to complete saving changes.

    Task 3: Create a Custom App Feature

    This task involves creating a custom app feature to which the Entities and oMDO can be assigned. The app feature allows you to logically group all your features together.

    Steps

    1. Create a custom app feature.

      Use the following data:

      App Feature IDActiveDescription
      Z_CA_CORE_DATA_IAM150CheckedCustom Data for IAM150 Training

      1. Log in to the SAP GUI.

      2. Enter /n/syclo/configpanel to launch the ConfigPanel.

      3. Once you are within the Config Panel (Web Dynpro opens in Browser), choose Mobile Application Configuration.

      4. Choose your mobile application and open the Features tab.

      5. Choose the Change button.

      6. Choose the Add feature button.

      7. Enter the information from the preceding table.

      8. Choose Save to save your changes.

        The features tab is selected. The UI elements mentioned in the stepas are highlighted.

    Task 4: oMDO Model Configuration

    This task involves the configuration of the oMDO Model. This includes creation of oData Model definition for entity type, entity set, association, association set, navigation property, and so on.

    Steps

    1. Create the oMDO Model for your mobile application.

      Use the following details.

      FieldValue
      Entity Type NameZ_##_PurchaseOrganization (Note: singular)
      Mobile ApplicationZIAM_##_SERVICE_ASSET_MANAGER
      oData Service IDZIAM150_INVENTORY_MANAGER_##-0001 (** make sure you choose the Asset Manager Mobile App Service in the dropdown)
      oMDO IDZIAM150_##_PURCHASE_ORG (oMDO Object created in previous task)
      oMDO Entity TypePURCHASEORG
      Entity Set Name.Z_##_PurchaseOrganizations (Note: plural)
      ActiveYes
      App Feature ID

      Z_CA_CORE_DATA_IAM150

      Assign to the feature created in the previous step.

      1. Choose the ConfigPanel Home button.

      2. Choose oData Model Configuration in the oData Channel Integration Settings section.

      3. Once you are within the mobile application oData Mode Details, use the Mobile Application Filter dropdown to choose your mobile application IAM150-## (ZIAM_##_ASSET_MANAGER)

      4. Expand your application and choose the Create button and enter the data given in the table.

    2. Add the following properties to the oData Model:

      Property NameoMDO Field NameEdm TypeKey
      PurchasingOrgEKORGEdm.StringX
      DescriptionEKOTXEdm.String 
      CompanyCodeBUKRSEdm.String 
      1. Choose the Property List tab.

      2. Choose Add Property and add the properties as given in the properties table.

    3. Save your changes.

      1. Choose the Save button at the top of the screen to save your changes (use the same Request you created previously).

        The Property List tab is selected.

    Task 5: Persona Assignment

    This task involves the assignment of the oMDO → Feature and then Feature → User Persona.

    Steps

    1. Assign oMDO to Feature.

      1. Log in to the SAP GUI.

      2. Enter /n/syclo/configpanel to launch the ConfigPanel.

      3. Once you are within the Config Panel (Web Dynpro opens in Browser), choose Component Assignment in the General Info section.

      4. Once you are within the Application Assignment Configuration, on your Mobile Application chooseZIAM_##_ASSET_MANAGER (IAM150-##)

      5. In the next screen, choose the oMOD Assignment tab.

      6. Choose the Change button.

      7. In the App Feature Id dropdown and select Z_CA_CORE_DATA_IAM150.

      8. In the oMDO ID dropdown, choose ZIAM150_##_PURCHASE_ORG.

      9. In the filtered Assignment List Table, set both In-Scope and Active Flag checkboxes to True.

      10. Choose Save to complete the assignment oMDO to the feature.

        To complete the assignment, choose Save.
    2. Assign Feature to Persona.

      1. Choose the User Personas tab.

      2. In the User Persona dropdown, choose INVENTORY_CLERK persona.

      3. In the App Feature Id dropdown, choose Z_CA_CORE_DATA_IAM150.

      4. In the Feature Assignment table, set both In Scope and Activate Flag checkboxes to True.

      5. Choose the Save button to save your changes to complete assignment of the feature to the persona.

        To complete the assignment, choose Save.

    Task 6: Test Your Changes Using the Gateway Client

    Steps

    1. Clear oData Service cache for your service.

      1. Log in to the SAP GUI and enter the transaction code /n/IWFND/MAINT_SERVICE and choose Enter.

      2. Navigate to the service ZIAM_##_ASSET_MANAGER version 1.

        Note that the ZIAM_##_INVENTORY_MANAGER Service is a subset of this composite service. The cache clean-up of Asset Manager Service will automatically cascade to the subset.

        Note

        For additional information, check the oData Service Assignment in Config Panel to see how the Services are assigned to your Mobile Applications and the Composite Settings.

      3. In the System Aliases section, choose the Service Implementation button.

      4. In the next screen, choose Cleanup Cache.

      5. Back on the /IWFND/MAINT_SERVICE screen, choose the Load Metadata button.

        Choose Service Implementation, then choose Load Metadata.A dialog box shows the message that the metadata has been reloaded.

    2. Test the Service using Gateway Client.

      1. While in the /IWFND/MAINT_SERVICE in the ICF Nodes section (at bottom left), choose the SAP Gateway Client to test the service using the Gateway Client.

        Note

        When you launch the Gateway Client (/IWFND/GW_CLIENT) via Maintain Service (/IWFND/MAINT_SERVICE) the Request URI is defaulted else you can enter /sap/opu/odata/sap/ZIAM_##_SAP_ASSET_MANAGER/?$format=xml

      2. Choose Execute to verify the service is working.

        Verify the ~status_code = 200

      3. From the Application toolbar, choose the EntitySets button.

      4. Choose Z_##_PurchaseOrganizations Entity set.

      5. The Request URI is updated to fetch the PurchaseOrganizations Entity set /sap/opu/odata/sap/ZIAM_##_ASSET_MANAGER/PurchaseOrganizations

      6. Choose Execute.

        Screenshot of the SAP Gateway Client showing the XML file.
      7. In the HTTP Response, verify that ~status_code = 200 and some data is returned in the response window.

    Task 7: Sync Service to Update Metadata in BAS

    Steps

    1. Once you have successfully tested PurchaseOrganizations via SAP Gateway, you can sync the service in BAS to update the Metadata.

      1. Log in to the SAP Business Application Studio.

      2. Open Project ZSAMComponent.

      3. Navigate to ServicesAssetManager.service.

      4. Once within the AssetManager.service, choose the Sync Service button to update the Model.

      5. Verify the AssetManager.xml to see if the PurchaseOrganizations is downloaded.

    Create a Purchase Requisition via SAP GUI

    Business Scenario

    In this exercise, you first create a Purchase Requisition in SAP GUI so that we can test the download of Purchase Requisition to Mobile Device. Later in this unit, we create the Purchase Requisition from Mobile Device.

    Note

    The steps below are giving a guide so that you can perform this exercise in your own system landscape.

    Steps

    1. Create a Purchase Requisition in SAP GUI TCode ME51n.

      Note

      We use this data later when creating the Purchase Requisition from the Mobile Client.

      FieldValue
      Purchase Document TypeNB (default selection)
      MaterialA500-00
      Quantity10 (Unit PC filled automatically)
      Plant1010
      Storage Location0001
      Purchase Organization1010
      RequisitionerIAM150-##
      FieldValue
      Item10 (populated automatically)
      Purchase GroupZ00 (derived from Plant)
      Short TextOil pump 500/00
      Unit of MeasurePC (derived from Material)
      Delivery DateCurrent date
      Delivery Date CategoryD (default value–Day Format)
      Material GroupL003 (derived from Material)
      Valuation Price46.50 (derived from Material Accounting view)
      CurrencyEUR
      Price Unit1
      Created ByCurrent user

      This data is populated automatically.

      Screenshot of the Create Purchase Requisition screen.
      1. Execute transaction ME51N.

      2. Enter the data as given in the tables above.

    Download Purchase Requisition (Part-1: Back-end)

    Note

    Use Transaction SE24 and there the reference class handler /MERP/CL_MM_PURCHASE_REQ_OD to create your copy Zxxx files. The code snippets provided in this handbook are examples for your reference only. Copy the required coding from the reference class.

    Note

    The steps below are giving a guide so that you can perform this exercise in your own system landscape.

    Task 1: Create oMDO Class Handler: Development Tasks

    Steps

    1. Create an oMDO Class for fetching Purchase Requisition data from SAP with the following data:

      FieldValue
      DescriptionPurchase Requisition OMDO Handler for IAM_##
      Instance GenerationPublic
      Usual ABAP Class<Select the radio button>
      Final<Uncheck the checkbox>
      1. Log in to the SAP system and navigate to transaction code SE24.

      2. Enter ZIAM_##_CL_MM_PURCHASE_REQ.

      3. Choose Create.

      4. In the pop-up window, choose (the default) Object Type Class radio button.

      5. Choose the Enter button.

      6. Enter the details as given in the table.

      7. Select the Save button.

      8. On the next pop-up window, choose the Local Object button and choose Save (or enter Package as $TMP).

    2. Set the super class of this class to /MERP/CL_CORE_OMDO_HNDLER_BASE.

      1. Once you are in the class, choose the Properties tab.

      2. Choose the Superclass button.

      3. Enter /MERP/CL_CORE_OMDO_HNDLER_BASE in the superclass name.

      4. Verify that the Final check box is unchecked.

      5. Choose the Save button.

        At this point, you notice that there are few interfaces and method loaded in the corresponding tabs.

        Note

        Set up your environment for better legibility by choosing in the menu bar UtilitiesSettingsClass Builder tab, check the Display Aliases and Group by Interfaces and Superclasses and choose Enter.

    3. Add Object Types.

      Use the following data:

      TypeProtectedAssociated TypeDescription
      GTYP_INPUT_FILTER_VALS_STRProtected Purchase Requisition Filters oMDO
      GTYP_OBJKEY_STRProtected  
      GTYP_PREQ_KEY_STRProtected  
      GTYP_PREQ_HDR_KEY_STRProtected  
      GTYP_PREQ_ACC_ASGN_KEY_STRProtected  
      GTYP_PREQ_KEY_TABProtected  

      1. Choose the Types tab.

      2. Enter the data as given in the preceding table.

      3. Choose Direct Type Entry.

      4. If prompted, choose Save changes.

      5. In the protected sectionenter the following code.

        Code Snippet
        123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
        types: BEGIN OF gtyp_dof_filter_vals_str, object_distribution_mode TYPE REF TO /mfnd/core_range_tab, preq_doc_cat TYPE REF TO /mfnd/core_range_tab, preq_doc_type TYPE REF TO /mfnd/core_range_tab, preq_date TYPE REF TO /mfnd/core_range_tab, open_items_only TYPE REF TO /mfnd/core_range_tab, purch_group TYPE REF TO /mfnd/core_range_tab, purch_org TYPE REF TO /mfnd/core_range_tab, purch_agreement TYPE REF TO /mfnd/core_range_tab, vendor TYPE REF TO /mfnd/core_range_tab, suppl_plnt TYPE REF TO /mfnd/core_range_tab, created_by TYPE REF TO /mfnd/core_range_tab, material TYPE REF TO /mfnd/core_range_tab, matl_group TYPE REF TO /mfnd/core_range_tab, item_cat TYPE REF TO /mfnd/core_range_tab, acctasscat TYPE REF TO /mfnd/core_range_tab, trackingno TYPE REF TO /mfnd/core_range_tab, delete_ind TYPE REF TO /mfnd/core_range_tab, preq_on_demand TYPE REF TO /merp/mm_preq_ondemand_tab, user_location TYPE REF TO /merp/mm_user_location_tab, user_rule_enabled TYPE REF TO /mfnd/core_range_tab, disable_fetch TYPE REF TO /mfnd/core_range_tab, preq_status TYPE REF TO /mfnd/core_range_tab, header_text_id TYPE REF TO /mfnd/core_range_tab, item_text_id TYPE REF TO /mfnd/core_range_tab, max_no_of_hits TYPE REF TO /mfnd/core_range_tab, automatic_source TYPE REF TO /mfnd/core_range_tab, skip_item_with_error TYPE REF TO /mfnd/core_range_tab, END OF gtyp_dof_filter_vals_str . types: BEGIN OF gtyp_input_filter_vals_str, banfn TYPE REF TO /mfnd/core_range_tab, END OF gtyp_input_filter_vals_str . types: BEGIN OF gtyp_objkey_str, banfn TYPE banfn, bnfpo TYPE bnfpo, packno TYPE packno, END OF gtyp_objkey_str . types: BEGIN OF gtyp_preq_key_str, banfn TYPE banfn, bnfpo TYPE bnfpo, END OF gtyp_preq_key_str . types: BEGIN OF gtyp_preq_hdr_key_str, banfn TYPE banfn, END OF gtyp_preq_hdr_key_str . constants CONST_PREQ_ENTITY type /MFND/CORE_TECH_ENTITY_TYP_DTE value 'PREQ' ##NO_TEXT. constants CONST_PREQ_HDR_ENTITY type /MFND/CORE_TECH_ENTITY_TYP_DTE value 'PREQHDR' ##NO_TEXT. constants CONST_PREQ_ACC_ASGN_ENTITY type /MFND/CORE_TECH_ENTITY_TYP_DTE value 'PREQACCASGN' ##NO_TEXT. types: gtyp_objkey_tab TYPE STANDARD TABLE OF gtyp_objkey_str . types: gtyp_hdrkey_tab TYPE STANDARD TABLE OF gtyp_preq_hdr_key_str . types: gtyp_preq_key_tab TYPE STANDARD TABLE OF gtyp_preq_key_str . data STR_DOF_FILTER_VALS type GTYP_DOF_FILTER_VALS_STR . data STR_INPUT_FILTER_VALS type GTYP_INPUT_FILTER_VALS_STR . data GREF_OMDO_DATA type ref to /MFND/CL_CORE_OMDO_DATA . data GREF_PREQ_BADI type ref to /MERP/MM_OMDO_PREQ_BADI . data GV_MAX_NO_OF_HIT type SY-INDEX .
      6. Save changes.

    4. Add attributes to your class with the following details.

      Attribute NameLevelVisibilityAssociated TypeDescriptionInitial Value
      CONST_PREQ_ENTITYConstantPublic/MFND/CORE_TECH_ENTITY_TYP_DTEoMDO - Technical Entity Type'PREQ'
      CONST_PREQ_HDR_ENTITConstantPublic/MFND/CORE_TECH_ENTITY_TYP_DTEoMDO - Technical Entity Type'PREQHDR'
      CONST_PREQ_ACC_ASGN_ENTITYConstantPublic/MFND/CORE_TECH_ENTITY_TYP_DTEoMDO - Technical Entity Type'PREQACCASGN'
      CONST_PREQ_NOTE_ENTITYConstantPublic/MFND/CORE_TECH_ENTITY_TYP_DTEoMDO - Technical Entity TypePREQNOTE
      STR_DOF_FILTER_VALSInstance AttributeProtectedGTYP_DOF_FILTER_VALS_STR  
      STR_INPUT_FILTER_VALSInstance AttributeProtectedGTYP_INPUT_FILTER_VALS_STR  

      Note

      Single quotes are required for the Initial Value 'PREQ', 'PREQHDR' and 'PREQACCASGN'

      1. Choose the Attributes tab.

      2. Enter the data as given in the preceding table.

    5. Redefine the method DEFINE_BO_ENTITY_MODEL with the following code:

      Code Snippet
      123456789
      method /MFND/IF_CORE_OMDO_BO_MODEL~DEFINE_BO_ENTITY_MODEL. CLEAR et_bo_entities. et_bo_entities = VALUE #( ( tech_entity_type = const_preq_entity ref_struct = '/MERP/MM_PURCHASE_REQ_ENTY_STR' flag_lead_entity = abap_true ) ( tech_entity_type = const_preq_hdr_entity ref_struct = '/MERP/MM_PURCHASE_REQ_ENTY_STR' ) ( tech_entity_type = const_preq_acc_asgn_entity ref_struct = '/MERP/MM_PREQ_ACCASGN_ENTY_STR' ) ). endmethod.
      1. Choose the Methods tab.

      2. Choose the Find button and search for Method DEFINE_BO_ENTITY_MODEL.

      3. Choose the Redefine button.

      4. Clear the code within the method and copy paste the given code in method.

      5. Check syntax (Ctrl + F2).

      6. Choose Save.

      7. Repeat the steps for the rest of the methods.

    6. Redefine the method GET_OBJKEYS_BY_DISTRIB_RULES with the following code:

      Code Snippet
      1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
      METHOD get_objkeys_by_distrib_rules. "Insert Start S4MERP SP11 bugid S4MOBADDON-2931 DATA: ls_preq TYPE gtyp_preq_key_str, ls_preq_hdr TYPE gtyp_preq_hdr_key_str, ls_preq_acc_asgn TYPE gtyp_preq_acc_asgn_key_str, lv_object_key TYPE /mfnd/core_bo_object_key_dte. *Get OnDemand List READ TABLE str_dof_filter_vals-preq_on_demand->* INTO DATA (ls_preq_on_demand) INDEX 1. * Get Purchase Requisition(PR) Keylist (EBAN) get_objkeys_preqs( EXPORTING is_entity_input_info = is_entity_input_info iref_omdo_data = cref_omdo_data IMPORTING et_objkeys = DATA(lt_objkeys) ). APPEND INITIAL LINE TO tab_bo_entity_keys_distr_rule ASSIGNING FIELD-SYMBOL(). APPEND INITIAL LINE TO tab_bo_entity_keys_distr_rule ASSIGNING FIELD-SYMBOL(). -tech_entity_type = const_preq_entity. -key_field_info = build_key_field_info_list( is_key_struct = ls_preq ). -tech_entity_type = const_preq_hdr_entity. -key_field_info = build_key_field_info_list( is_key_struct = ls_preq_hdr ). LOOP AT lt_objkeys ASSIGNING FIELD-SYMBOL(). DATA(lv_preq_key) = CONV char255( -banfn && -bnfpo ). INSERT lv_preq_key INTO TABLE -object_keylist. DATA(lv_preqhdr_key) = CONV char255( -banfn ). INSERT lv_preqhdr_key INTO TABLE -object_keylist. ENDLOOP. DELETE ADJACENT DUPLICATES FROM -object_keylist COMPARING ALL FIELDS. DELETE ADJACENT DUPLICATES FROM -object_keylist COMPARING ALL FIELDS. * Get PR Account Assignment Keylist(EBKN) IF ls_preq_on_demand-preq_account_assignment = 'X'. get_objkeys_preq_acc_asgn( EXPORTING it_objkeys = lt_objkeys IMPORTING et_preq_acc_asgn_keys = DATA(lt_preq_acc_asgn_keys) ). APPEND INITIAL LINE TO tab_bo_entity_keys_distr_rule ASSIGNING FIELD-SYMBOL(). -tech_entity_type = const_preq_acc_asgn_entity. -key_field_info = build_key_field_info_list( is_key_struct = ls_preq_acc_asgn ). LOOP AT lt_preq_acc_asgn_keys ASSIGNING FIELD-SYMBOL(). lv_object_key = CONV char255( -banfn && -bnfpo && -zebkn ). INSERT lv_object_key INTO TABLE -object_keylist. ENDLOOP. ENDIF. ENDMETHOD.
      1. Perform the steps as described in the previous step.

    7. Redefine the method INITIALIZE_REQUEST_PROCESSING with the following code:

      Code Snippet
      123456789101112131415161718192021222324252627282930313233
      METHOD initialize_request_processing. "Set reference to oMDO container gref_omdo_data = cref_omdo_data. "DOF filters CREATE DATA: str_dof_filter_vals-preq_on_demand, str_dof_filter_vals-ondemand_mapping, str_dof_filter_vals-user_location. map_filter_values_to_structure( EXPORTING iv_operation = omdo_operation CHANGING cs_filters = str_dof_filter_vals ). IF omdo_operation = const_omdo_core_op_read AND str_dof_filter_vals-max_no_of_hits->* IS NOT INITIAL. /smfnd/cl_core_mdo_tools=>get_simple_val_from_range( EXPORTING it_range_table = str_dof_filter_vals-max_no_of_hits->* IMPORTING ev_low = gv_max_no_of_hit ). LOOP AT str_dof_filter_vals-created_by->* ASSIGNING FIELD-SYMBOL(). IF -low = 'SY-UNAME'. -low = sy-uname. ENDIF. ENDLOOP. ENDIF. "URL Input $Filters LOOP AT cref_omdo_data->tab_odata_v2_req_info ASSIGNING FIELD-SYMBOL(). cref_omdo_data->map_entity_input_field_filters( EXPORTING iv_request_no = -request_no iv_tech_entity_type = -tech_entity_type CHANGING cs_filters = str_input_filter_vals ). ENDLOOP. ENDMETHOD.
      1. Perform the steps as described in the previous step.

    8. Redefine the method GET_OPER_FIELD_CATALOG_TABLES with the following code:

      Code Snippet
      123456789101112131415161718192021222324252627
      METHOD /mfnd/if_core_omdo_field_cat~get_oper_field_catalog_tables. "Insert Start S4MERP SP11 bugid S4MOBADDON-2931 super->get_oper_field_catalog_tables( IMPORTING et_field_catalog_tables = et_field_catalog_tables et_exclusion_field_list = et_exclusion_field_list et_required_field_list = et_required_field_list ). et_field_catalog_tables = VALUE #( ( omdo_handler = clsname operation = const_omdo_core_op_read tabname = 'EBAN' ) ( omdo_handler = clsname operation = const_omdo_core_op_read tabname = 'EBKN' ) ). et_required_field_list = VALUE #( "Purchase Requisition (PR) ( omdo_handler = clsname operation = const_omdo_core_op_read tabname = 'EBAN' fieldname = 'BANFN' ) ( omdo_handler = clsname operation = const_omdo_core_op_read tabname = 'EBAN' fieldname = 'BNFPO' ) ( omdo_handler = clsname operation = const_omdo_core_op_read tabname = 'EBAN' fieldname = 'SPRAS' ) "PR Account Assignment ( omdo_handler = clsname operation = const_omdo_core_op_read tabname = 'EBKN' fieldname = 'BANFN' ) ( omdo_handler = clsname operation = const_omdo_core_op_read tabname = 'EBKN' fieldname = 'BNFPO' ) ( omdo_handler = clsname operation = const_omdo_core_op_read tabname = 'EBKN' fieldname = 'ZEBKN' ) ). "Insert End S4MERP SP11 bugid S4MOBADDON-2931 ENDMETHOD.
      1. Perform the steps as described in the previous step.

    9. Redefine the method GET_DATA_FILTER_LIST with the following code:

      Code Snippet
      1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
      METHOD /mfnd/if_core_omdo_filter_serv~get_data_filter_list. REFRESH et_data_filters. et_data_filters = VALUE #( "Read Operation ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'OBJECT_DISTRIBUTION_MODE' dof_group = /mfnd/cl_core_std_omdo_dofgrp=>std_dofgrp_distrmod usage_tabname = '/MERP/CORE_OMDO_DISTR_STR' usage_fieldname = 'GEN_ASGMNT_TYPE' mandatory = abap_true ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'PREQ_ON_DEMAND' usage_tabname = '/MERP/MM_PREQ_ONDEMAND_STR' dof_group = /mfnd/cl_core_std_omdo_dofgrp=>std_dofgrp_dataseg dof_type = /mfnd/if_core_omdo_const=>omdo_doftype_tablerule filter_status = /mfnd/if_core_omdo_const=>filter_stat_std tech_name_only = 'X') ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'USER_LOCATION' usage_tabname = '/MERP/MM_USER_LOCATION_STR' dof_type = const_filter_type_table dof_group = /mfnd/cl_core_std_omdo_dofgrp=>std_dofgrp_dataseg ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'USER_RULE_ENABLED' usage_tabname = '/SYCLO/CA000P' usage_fieldname = 'PARAM_VALUE' dof_group = /mfnd/cl_core_std_omdo_dofgrp=>std_dofgrp_dataseg ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'PREQ_DOC_CAT' usage_tabname = 'EBAN' usage_fieldname = 'BSTYP' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'PREQ_DOC_TYPE' usage_tabname = 'EBAN' usage_fieldname = 'BSART' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'PREQ_DATE' usage_tabname = 'EBAN' usage_fieldname = 'BADAT' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'OPEN_ITEMS_ONLY' usage_tabname = 'EBAN' usage_fieldname = 'EBAKZ' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'PURCH_GROUP' usage_tabname = 'EBAN' usage_fieldname = 'EKGRP' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'PURCH_ORG' usage_tabname = 'EBAN' usage_fieldname = 'EKORG' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'PURCH_AGREEMENT' usage_tabname = 'EBAN' usage_fieldname = 'KONNR' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'VENDOR' usage_tabname = 'EBAN' usage_fieldname = 'LIFNR' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'SUPPL_PLNT' usage_tabname = 'EBAN' usage_fieldname = 'RESWK' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'CREATED_BY' usage_tabname = 'EBAN' usage_fieldname = 'ERNAM' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'MATERIAL' usage_tabname = 'EBAN' usage_fieldname = 'MATNR' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'MATL_GROUP' usage_tabname = 'EBAN' usage_fieldname = 'MATKL' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'ITEM_CAT' usage_tabname = 'EBAN' usage_fieldname = 'PSTYP' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'ACCTASSCAT' usage_tabname = 'EBAN' usage_fieldname = 'KNTTP' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'TRACKINGNO' usage_tabname = 'EBAN' usage_fieldname = 'BEDNR' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'DELETE_IND' usage_tabname = 'EBAN' usage_fieldname = 'LOEKZ' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'DISABLE_FETCH' usage_tabname = '/MFND/CORE_BOOLEAN_STR' usage_fieldname = 'BOOLEAN' ) ( omdo_handler = clsname operation = const_omdo_core_op_read dof_name = 'MAX_NO_OF_HITS' usage_tabname = 'SYST' usage_fieldname = 'INDEX' filter_status = /syclo/cl_core_constants=>filter_stat_std ) ). ENDMETHOD.
      1. Perform the steps as described in the previous step.

    10. Next create the method GET_OBJKEYS_PREQS with the following code:

      Code Snippet
      1234567891011121314151617181920
      METHOD get_objkeys_preqs. REFRESH et_objkeys. DATA: lt_objkeys_tmp TYPE gtyp_objkey_tab, lt_objkeys TYPE gtyp_objkey_tab. IF /mfnd/cl_core_constants=>omdo_filter IN str_dof_filter_vals-object_distribution_mode->*. get_objkeys_for_distr_mode_1( IMPORTING et_object_keylist = lt_objkeys_tmp ). APPEND LINES OF lt_objkeys_tmp TO lt_objkeys. ENDIF. IF /mfnd/cl_core_constants=>dep_queue IN str_dof_filter_vals-object_distribution_mode->*. CLEAR lt_objkeys_tmp. get_objkeys_for_distr_mode_2( IMPORTING et_object_keylist = lt_objkeys_tmp ). APPEND LINES OF lt_objkeys_tmp TO lt_objkeys. flag_bo_distr_key_calc_accumu = abap_true. ENDIF. et_objkeys = lt_objkeys. ENDMETHOD.
      1. Perform the steps as described in the previous step.

    11. Create the method GET_OBJKEYS_FOR_DISTR_MODE_1 with the following code:

      Code Snippet
      123456789101112131415161718192021222324252627282930313233
      METHOD get_objkeys_for_distr_mode_1. REFRESH et_object_keylist. IF str_dof_filter_vals-user_location->* IS NOT INITIAL. READ TABLE str_dof_filter_vals-user_rule_enabled->* ASSIGNING FIELD-SYMBOL() INDEX 1. DATA(lv_user_rule_enabled) = -low. ENDIF. DATA lt_objkeys TYPE gtyp_objkey_tab. IF str_dof_filter_vals-user_location->* IS NOT INITIAL AND lv_user_rule_enabled = abap_true. SELECT banfn bnfpo packno FROM eban "#EC CI_NOORDER INTO TABLE lt_objkeys UP TO gv_max_no_of_hit ROWS FOR ALL ENTRIES IN str_dof_filter_vals-user_location->* WHERE werks = str_dof_filter_vals-user_location->*-werks AND lgort = str_dof_filter_vals-user_location->*-lgort AND bstyp IN str_dof_filter_vals-preq_doc_cat->* AND bsart IN str_dof_filter_vals-preq_doc_type->* AND badat IN str_dof_filter_vals-preq_date->* AND ekorg IN str_dof_filter_vals-purch_org->* AND ekgrp IN str_dof_filter_vals-purch_group->* AND lifnr IN str_dof_filter_vals-vendor->* AND reswk IN str_dof_filter_vals-suppl_plnt->* AND ernam IN str_dof_filter_vals-created_by->* AND matnr IN str_dof_filter_vals-material->* AND matkl IN str_dof_filter_vals-matl_group->* AND knttp IN str_dof_filter_vals-acctasscat->* AND loekz IN str_dof_filter_vals-delete_ind->* %_HINTS HDB '&max_in_blocking_factor 32767&' ##NO_TEXT. "#EC CI_HINTS. ENDIF. APPEND LINES OF lt_objkeys TO et_object_keylist. ENDMETHOD.
      1. Perform the steps as described in the previous step.

    12. Create the method GET_OBJKEYS_FROM_DEP_QUEUE with the following code:

      Code Snippet
      123456789101112131415161718192021222324252627282930
      Method GET_OBJKEYS_FROM_DEP_QUEUE. "Insert Start S4MERP SP11 bugid S4MOBADDON-2931 REFRESH et_objkeys. "Get table of Dep. Keylits, 1 row per Origin DATA (lt_depobj_keylists) = /mfnd/cl_core__depobj_queue_mgr=>get_user_dep_objkeys_by_orig( iv_user_guid = user_guid iv_dep_omdo_id = str_omdo_general_settings-omdo_id iv_dep_tech_entire_type = const_preq_entity ) . IF gref_preq_badi IS NOT INITIAL CALL BADI gref_preq_badi->get_objkeys_from_dep_queue EXPORTING iref_cmdo_data = gref_omdo_data iv_user_guid = user_guid iv_omdo_id = str_omdo_general_setting-omdo_id iv_tech_entity_type = const_preq_entity CHANGING ct_dep_object_keylists = lt_depobj_keylists. ENDIF LOOP AT lt_depobj_keylists ASSIGNING FIELD-SYMBOL(<keylist>). LOOP AT <keylist>-key_list ASSIGNING FIELD-SYMBOL(<depobj_key>). APPEND <depobj_key> TO et_objkeys. ENDLOOP. ENDLOOP. "Insert End S4MERP SP11 bugid S4MOBADDON-2931 ENDMETHOD
      1. Perform the steps as described in the previous step.

    13. Create the method GET_OBJKEYS_FOR_DISTR_MODE_2 with the following code:

      Code Snippet
      123456789101112131415161718
      METHOD get_objkeys_for_distr_mode_2. REFRESH et_object_keylist. get_objkeys_from_dep_queue( IMPORTING et_objkeys = DATA(lt_objkeys) ). SORT lt_objkeys BY banfn. DELETE ADJACENT DUPLICATES FROM lt_objkeys COMPARING banfn. IF lt_objkeys IS NOT INITIAL. SELECT eban~banfn eban~bnfpo eban~packno FROM eban INTO TABLE et_object_keylist FOR ALL ENTRIES IN lt_objkeys WHERE eban~banfn = lt_objkeys-banfn %_HINTS HDB '&max_in_blocking_factor 32767&' ##NO_TEXT. "#EC CI_HINTS. ENDIF. ENDMETHOD.
      1. Perform the steps as described in the previous step.

    14. Create the method GET_OBJKEYS_PREQ_ACC_ASGN with the following code:

      Code Snippet
      1234567891011121314
      METHOD get_objkeys_preq_acc_asgn. CHECK it_objkeys IS NOT INITIAL. REFRESH et_preq_acc_asgn_keys. SELECT banfn bnfpo zebkn FROM ebkn INTO TABLE et_preq_acc_asgn_keys FOR ALL ENTRIES IN it_objkeys WHERE banfn = it_objkeys-banfn AND bnfpo = it_objkeys-bnfpo. "Insert End S4MERP SP11 bugid S4MOBADDON-2931 ENDMETHOD
      1. Perform the steps as described in the previous step.

    15. Redefine the method LOAD_ENTITY_DETAILS with the following code:

      Code Snippet
      123456789101112131415
      METHOD load_entity_details. CASE is_entity_input_info-tech_entity_type. WHEN const_preq_entity. get_preqs( EXPORTING is_entity_input_info = is_entity_input_info CHANGING cref_omdo_data = cref_omdo_data ). WHEN const_preq_hdr_entity. get_preqs_header( EXPORTING is_entity_input_info = is_entity_input_info CHANGING cref_omdo_data = cref_omdo_data ). WHEN const_preq_acc_asgn_entity. get_preq_acc_asgn( EXPORTING is_entity_input_info = is_entity_input_info CHANGING cref_omdo_data = cref_omdo_data ). ENDMETHOD.
      1. Perform the steps as described in the previous step.

    16. Create the method GET_PREQS with the following code:

      Code Snippet
      1234567891011121314151617181920212223242526272829303132
      METHOD get_preqs. "Tables & Structures DATA: lt_preq_data TYPE STANDARD TABLE OF /merp/mm_purchase_req_enty_str, lt_preq_keys TYPE STANDARD TABLE OF gtyp_preq_key_str. *---Main Section log_method_call( ). GET REFERENCE OF lt_preq_data INTO DATA(lref_preq_data). DATA(lref_object_keylist) = load_delta_load_keylist( iv_tech_entity_type = const_preq_entity ). IF lref_object_keylist->*-object_keylist IS NOT INITIAL. LOOP AT lref_object_keylist->*-object_keylist ASSIGNING FIELD-SYMBOL(). APPEND TO lt_preq_keys. ENDLOOP. DATA(lv_select_clause) = build_oper_field_select_string( iv_tabname = 'EBAN' iv_expanded_field_list = 'X' ). SELECT (lv_select_clause) FROM eban "#EC CI_HINTS INTO CORRESPONDING FIELDS OF TABLE lref_preq_data->* FOR ALL ENTRIES IN lt_preq_keys WHERE eban~banfn = lt_preq_keys-banfn AND eban~bnfpo = lt_preq_keys-bnfpo %_HINTS HDB '&max_in_blocking_factor 32767&' ##NO_TEXT. ENDIF. cref_omdo_data->add_omdo_output_single( iv_tech_entity_type = is_entity_input_info-tech_entity_type iv_request_no = is_entity_input_info-request_no iref_data = lref_preq_data ). ENDMETHOD.
      1. Perform the steps as described in the previous step.

    17. Next create the method GET_PREQS_HEADER with the following code:

      Code Snippet
      123456789101112131415161718192021222324252627282930
      METHOD get_preqs_header. "Tables & Structures DATA: lt_preq_data TYPE STANDARD TABLE OF /merp/mm_purchase_req_enty_str, lt_preq_keys TYPE STANDARD TABLE OF gtyp_preq_hdr_key_str. *---Main Section log_method_call( ). GET REFERENCE OF lt_preq_data INTO DATA(lref_preq_data). DATA(lref_object_keylist) = load_delta_load_keylist( iv_tech_entity_type = const_preq_hdr_entity ). IF lref_object_keylist->*-object_keylist IS NOT INITIAL. LOOP AT lref_object_keylist->*-object_keylist ASSIGNING FIELD-SYMBOL(). APPEND TO lt_preq_keys. ENDLOOP. LOOP AT lt_preq_keys ASSIGNING FIELD-SYMBOL(). APPEND INITIAL LINE TO lt_preq_data ASSIGNING FIELD-SYMBOL(). -banfn = -banfn. ENDLOOP. SORT lt_preq_data BY banfn. DELETE ADJACENT DUPLICATES FROM lt_preq_data COMPARING banfn. ENDIF. cref_omdo_data->add_omdo_output_single( iv_tech_entity_type = is_entity_input_info-tech_entity_type iv_request_no = is_entity_input_info-request_no iref_data = lref_preq_data ). ENDMETHOD.
      1. Perform the steps as described in the previous step.

    18. Next create the method GET_PREQ_ACC_ASGN with the following code:

      Code Snippet
      1234567891011121314151617181920212223242526272829303132333435
      METHOD get_preq_acc_asgn. "Insert Start S4MERP SP11 bugid S4MOBADDON-2931 "Tables & Structures DATA: lt_preq_accasgn_data TYPE STANDARD TABLE OF /merp/mm_preq_accasgn_enty_str, lt_preq_accasgn_keys TYPE STANDARD TABLE OF gtyp_preq_acc_asgn_key_str. *---Main Section log_method_call( ). GET REFERENCE OF lt_preq_accasgn_data INTO DATA(lref_preq_accasgn_data). DATA(lref_object_keylist) = load_delta_load_keylist( iv_tech_entity_type = const_preq_entity ). IF lref_object_keylist->*-object_keylist IS NOT INITIAL. LOOP AT lref_object_keylist->*-object_keylist ASSIGNING FIELD-SYMBOL(). APPEND TO lt_preq_accasgn_keys. ENDLOOP. DATA(lv_select_clause) = build_oper_field_select_string( iv_tabname = 'EBKN' iv_expanded_field_list = 'X' ). SELECT (lv_select_clause) FROM ebkn INTO CORRESPONDING FIELDS OF TABLE lref_preq_accasgn_data->* FOR ALL ENTRIES IN lt_preq_accasgn_keys WHERE banfn = lt_preq_accasgn_keys-banfn AND bnfpo = lt_preq_accasgn_keys-bnfpo AND zebkn = lt_preq_accasgn_keys-zebkn %_HINTS HDB '&max_in_blocking_factor 32767&' ##NO_TEXT. "#EC CI_HINTS. ENDIF. cref_omdo_data->add_omdo_output_single( iv_tech_entity_type = is_entity_input_info-tech_entity_type iv_request_no = is_entity_input_info-request_no iref_data = lref_preq_accasgn_data ). "Insert End S4MERP SP11 bugid S4MOBADDON-2931
      1. Perform the steps as described in the previous step.

    19. Activate the class.

      1. Go back to the class builder.

      2. Choose the Activate button (Ctrl+F3) and choose Enter on the pop-up window.

        In the screenshot, the Methods tab is highlighted.

    Task 2: Perform oMDO Object Configuration

    Note

    For the training, a mobile application (ZIAM_##_SERVICE_ASSET_MANAGER) is already created by copying a standard mobile app. (## refers to your group number).

    Note that the custom app is only for training purposes, in a project implementation you work directly with the standard mobile app.

    This task involves the configuration of the oMDO Object. This includes configuration for data extraction and distribution logic. It determines the runtime behavior of the class created in the previous step.

    Steps

    1. Create a new oMDO Object using the following details for your Mobile Application ZIAM-##.

      FieldValueExplanation
      oMDO IDZIAM150_##_PURCHASE_REQ 
      DescriptionZIAM150_## - Purchase Requisition 
      Mobile ApplicationZIAM-## 
      oMDO HandlerZIAM_##_CL_MM_PURCHASE_REQ (class created in previous task)Decided by super class /MERP/CL_CORE_OMDO_HNDLER_BASE
      Process FlowStandard Flow using Key List 
      Exempt Read Entity RequestFalse 
      Enable Client State Tracking.Checked 
      Enable periodic refresh.False 
      Refresh frequency.False 
      Optimal Client StateChecked 
      Support Delta SyncFalseWhen an Exchange Object is created and assigned, we set this to True. For now, set to False
      Data Distribution ModeAlways perform distrib. key calculation 
      Delta Object Key List Setup ModeDifference of Current and Last Data Distribution Keylist 
      Enable Paging.Checked 
      Paging Package size5000Number of records in each package
      Sync Session Max Idle Timeout120 
      Sync Priority.440Higher number as we want to download after other objects.
      1. Log in to the SAP GUI.

      2. Enter /n/syclo/configpanel to launch the ConfigPanel.

      3. Once you are within the Config Panel (Web Dynpro opens in Browser), choose oData Mobile Data Object Configuration in the oData Channel Integration Settings section.

      4. Use the Mobile Application Filter dropdown to choose your mobile application IAM150-## (ZIAM_##_ASSET_MANAGER).

        It is important that you choose the correct mobile app name.

      5. Select the mobile app and expand control on the left-hand side to view the oData Mobile data objects (oMDOs).

      6. Choose the Create button to create a new oMDO Object using the data given in the preceding table.

        On the screenshot, the General Settings tab is selected.
      7. Choose the Technical Model Info tab to view the Technical Entities exposed from oMDO Class Handler DEFINE_BO_ENTITY_MODEL.

      8. Navigate to the Field Selection tab and restrict the selection to EBAN, and EBKN tables.

        In this exercise, we will not fetch data from the rest of the tables.

      9. Choose the Data Filter and check the filters. Configure OBJECT_DISTRIBUTION_MODE filter = 1 OMDO filter (download data based on the filters in the config panel) set to TRUE.

        Filter = 2 – Dependency Queue (will ignore filters in config panel) do not configure initially.

        In the screenshot, the data Filter is highlighted.
      10. Expand the Data Segment and configure the following values:

        Data SegmentValue
        PREQ_ON_DEMAND

        PREQ_ITEMS=On

        PREQ_ACCOUNT_ASSGINMENT=On

        And the rest are Off.

        USER_LOCATION

        Plant= 1010

        Storage Location = 0001

        USER_RULE_ENABLEDX (set to True)
      11. Choose the Save button to save the changes.

      12. If requested, assign the configuration to a transport.

      13. Choose Continue to complete saving changes.

        Note

        Per the preceding configuration, only the Purchase Requisitions assigned to the Plant and Storage Location are downloaded. You can configure extra filters such as Created By (SY-UNAME) to restrict Purchase Requestions created by the current user.

    Task 3: Perform the oMDO Model Configuration

    This task involves the configuration of the oMDO Model. This includes creation of oData Model definition for entity type, entity set, association, association set, navigation property, and so on.

    Steps

    1. Create the oMDO Model for your mobile application.

      Use the following data:

      FieldValue
      Entity Type NameZ_##_PurchaseRequisition
      Mobile ApplicationZIAM_##_ASSET_MANAGER
      oData Service IDZIAM_INVENTORY_MANAGER_##-0001 (** make sure you choose the Asset Manager Mobile App Service in the dropdown)
      oMDO IDZIAM150_##_PURCHASE_REQ (oMDO Object created in previous task)
      oMDO Entity TypePREQ
      Entity Set Name.Z_##_PurchaseRequisitions
      Creatable<flag>
      ActiveYes
      App Feature ID

      Z_CA_CORE_DATA_150

      For the training purpose we will reuse the Feature, but in a Project implementation, consider an appropriate feature or create a new one if required.

      1. Choose ConfigPanel Home.

      2. Choose oData Model Configuration in the oData Channel Integration Settings section.

      3. Once you are within the Mobile Application oData Mode Details, use the Mobile Application Filter dropdown to choose your Mobile Application IAM150-## (ZIAM_##_ASSET_MANAGER).

      4. Expand your application and choose Create and enter the data given in the table.

        Choose Create and enter the data from the table.
    2. Add the following properties to the oData Model.

      Use the following data:

      Property NameOMDO Field NameEdm TypeKey
      PurchasingReqBANFNEdm.StringX
      RequisnItemBNFPOEdm.StringX
      CreatedByERNAMEdm.String 
      DeliveryDateLFDATEdm.String 
      DeliveryDateCategoryLPEINEdm.String 
      DocCategoryBSTYPEdm.String 
      DocTypeBSARTEdm.String 
      ItemEBELPEdm.String 
      MaterialMATNREdm.String 
      PlantWERKSEdm.String 
      PriceUnitPEINHEdm.String 
      PurchGroupEKGRPEdm.String 
      PurchasngOrgEKORGEdm.String 
      QuantityMENGEEdm.Decimal (13,3) 
      RequisitionerAFNAMEdm.String 
      RequisnDateBADATEdm.String 
      ShortTextTXZ01Edm.String 
      StorageLocationLGORTEdm.String 
      UOMMEINSEdm.String 
      ValuationPricePREISEdm.Decimal (11.2) 

      1. Choose the Property List tab.

      2. Choose Add Property and add the properties as given in the properties table.

      3. Choose the Save button at the top of the screen to save your changes (use the same request you created previously).

    3. Repeat the steps to create Z_PurchaseReqAcctAsign.

      Use the following data:

      FieldValue
      Entity Type NameZ_##_PurchaseReqAcctAsign
      Mobile ApplicationZIAM_##_ASSET_MANAGER
      oData Service IDZIAM_##_INVENTORY_MANAGER-0001 (** make sure you choose the Asset Manager Mobile App Service in the dropdown)
      oMDO IDZIAM_##_PURCHASE_REQ (oMDO Object created in previous task)
      oMDO Entity TypePREQACCASGN
      Entity Set NameZZ_##_PurchaseReqAcctAsigns
      ActiveYes
      App Feature ID

      Z_CA_CORE_DATA_IAM150

      For the training purpose we will reuse the Feature, but in a Project implementation, consider an appropriate feature or create a new one if necessary.

      Add the following properties to the oData Model:

      Property NameoMDO Field NameEdm TypeKey
      PurchasingReqBANFNEdm.StringX
      RequisnItemBNFPOEdm.StringX
      SerNoAcctAssignZEBKNEdm.StringX
      CostCenterKOSTLEdm.String 
      GLAccountSAKTOEdm.String 
      OrderAUFNREdm.String 

      1. Perform the steps as described previously.

    4. Navigate back to Z_##_PurchaseRequisition to add Association and Navigation.

      Use the following data:

      FieldValueComments
      Principal EntityZ_##_PurchaseRequisition 
      Dependent EntityZ_##_PurchaseReqAcctAsign 
      Principal Cardinality1 
      Dependent Cardinality0..n 
      Association Set NamePurchaseRequisition_AccountAssignment_ASThis is automatically populated.
      Association NamePurchaseRequisition_AccountAssignmentThis is automatically populated.

      1. Perform the steps as described previously.

        In the screenshot, the Association & Set List tab is selected.
    5. Create Referential Constraints.

      Use the following data:

      Principal Entity TypePrincipal PropertyDependent Entity TypeDependent Type
      Z_##_PurchaseRequisitionPurchaseReqZ_##_PurchaseReqAcctAsignPurchaseReq
      Z_##_PurchaseRequisitionRequisnItemZ_##_PurchaseReqAcctAsignRequisnItem

      1. Perform the steps as previously described.

        The result should look like:In the screenshot, the Referential Constraints tab is selected.

    6. Create the navigate property to Z_##_PurchaseReqAcctAsign to add association and navigation.

      Use the following data:

      FieldValueComments
      AssociationPurchaseRequisition_AccountAssignmentUsing the dropdown menu, select the Association and the rest of the fields are automatically populated.
      Principal Entity NameZ_##_PurchaseRequisition 
      Target Entity NameZ_##_PurchaseReqAcctAsign 
      Navigation Property NameZ_##_PurchaseReqAcctAssign_Nav 
      Technical NameZ_##_PURCHASEREQACCTASSIGN_NAV 

      1. Perform the steps as previously described.

        The result looks like the following image:In the screenshot, the Navigation Property List tab is selected.

    7. Save your changes.

      1. Choose the Save button at the top of the screen to save your changes (use the same request you created previously).

    Task 4: Perform Persona Assignment

    This task involves the assignment of the oMDO → Feature and then Feature → User Persona.

    Steps

    1. Assign oMDO to Feature.

      1. Log in to the SAP GUI.

      2. Enter /n/syclo/configpanel to launch the ConfigPane.

      3. Once you are within the Config Panel (Web Dynpro opens in Browser), choose Component Assignment in the General Info section.

      4. Once you are within the Application Assignment Configuration, choose your mobile application ZIAM_##_SERVICE_ASSET_MANAGER (IAM150-##).

      5. In the next screen, choose the oMOD Assignment tab.

      6. Choose the Change button.

      7. In the App Feature Id dropdown and select Z_CA_CORE_DATA_IAM150.

      8. In the oMDO ID dropdown and choose ZIAM_##_PURCHASE_REQ.

      9. In the filtered Assignment List table, choose the In-scope checkbox.

      10. Choose the Active checkbox to assign the oMDO to the feature.

    2. Assign Feature to Persona.

      In the previous task, we already assigned the feature to the Persona. However, if you created a new feature assign it to the Persona.

      1. Choose the User Personas tab.

      2. In the User Persona dropdown, choose INVENTORY_CLERK persona.

      3. In the App. Feature Id dropdown, choose Z_CA_CORE_DATA_IAM150.

      4. In the Feature Assignment table, choose the Activate checkbox to assign the feature to the persona.

      5. Choose the Save button to save your changes.

    Task 5: Test Your Changes Using the Gateway Client

    Steps

    1. Clear oData Service Cache for your service.

      1. Log in to SAP GUI.

      2. Enter the transaction code /N/IWFND/MAINT_SERVICE and choose Enter.

      3. Navigate to the service ZIAM_##_ASSET_MANAGER version 1.

        Note that the ZIAM_##_INVENTORY_MANAGER service is a subset of this composite service. The cache clean up of Asset Manager Service will automatically cascade to the subset.

        Note

        For additional information, check the oData Service Assignment in Config Panel to see how the services are assigned to your mobile applications and the composite settings.

      4. In the System Aliases section, choose the Service Implementation button.

      5. In the next screen, choose the Cleanup Cache button.

        A dialog box shows the message that the metadata has been reloaded.

      6. Back on the /IWFND/MAINT_SERVICE screen, choose the Load Metadata button.

    2. Test the Service in Gateway Client.

      1. In the /IWFND/MAINT_SERVICE screen navigate to the ICF Nodes section (at bottom left), choose the SAP Gateway Client to test the service using the Gateway Client.

        Note

        When you launch the Gateway Client (/IWFND/GW_CLIENT) via Maintain Service (/IWFND/MAINT_SERVICE) the Request URI is defaulted else you can enter /sap/opu/odata/sap/ZIAM_##_SAP_ASSET_MANAGER/?$format=xml

      2. Choose Execute to verify the service is working.

        Verify the ~status_code = 200.

      3. From the application toolbar, choose the EntitySets button.

      4. Choose Z_##_PurchaseRequisitions Entityset.

      5. The Request URI is updated to fetch the Z_##_PurchaseRequisitions Entityset/sap/opu/odata/sap/ZIAM_##_ASSET_MANAGER/Z_##_PurchaseRequisitions.

      6. Choose Execute.

      7. Repeat the steps for Z_##_PurchaseRequsitionsAcctAsgns.

        In the HTTP Response, verify that ~status_code = 200 and some data is returned in the response window.

        In the SAP Gateway Client, the response window is shown.
    3. Test from BTP Destination.

      Use: https://.../ /DEST_SAM2205_PPROP/Z_##_PurchaseRequisitions

      1. Perform the steps as described above, but now from the SAP BTP destination. The result is:

        Screenshot of the XML code.

        Note

        You can update the DEST_SAMxxxx_PPROP.ini file in BTP Offline Access feature to include Purchase Requisition in $batch

    Download Purchase Requisition (Part-2: MDK Metadata)

    Note

    The steps below are giving a guide so that you can perform this exercise in your own system landscape.

    Task 1: Enhance Inventory Overview Page to Display Purchase Requisitions

    We enhance the Inventory Overview page of the Inventory Persona and to display the Purchase Requisition in a new tab.

    Steps

    1. Copy the Overview Page from SAPAssetManager to the ZSAMComponent project and open it.

      1. Copy /SAPAssetManager/Pages/Inventory/InventoryOverview.pagetoto /ZSAMComponent/Pages/Inventory/InventoryOverview.page.

      2. Open the/ZSAMComponent/Pages/Inventory/InventoryOverview.page.

    2. Update the KPI Count to display the Purchase Requisitions.

      1. Search for the KPIItems section and add the following code after the Physical Inventory KPI count and before the Material Document Item Count.

        Note

        • Note that you must add a comma before and after the code insert.
        • We create the label and the rule for count later in this exercise.
        Code Snippet
        123456789
        { "MetricItems": [ { "Value": "/ZSAPComponent/Rules/Inventory/Overview/Z_PurchaseRequsitionKPIItemsCount.js" } ], "CaptionLabel": "$(L, z_purchaseRequisition_label)" },
    3. Add a code for a new tab to display Purchase Requisitions.

      Insert the following code after the Physical Inventory tab and before the Recent Tab section.

      1. Search for the Physical Inventory section and add the following code after the Physical Inventory tab and before the Recent tab section.

        Note

        • Note that you must add a comma before and after the code insert.
        • We create the label and the rule for List Page in the later in this exercise.
        Code Snippet
        1234567
        { "_Name": "Z_PurchaseRequisitionTab", "Caption": "$(L, z_purchaseRequisition_label)", "PageToOpen" : "/ZSAPComponent/Pages/Inventory/Z_PurchaseRequisition/Z_PurchaseRequisitionList.page", "_Type": "Control.Type.TabItem" },
    4. While in the Inventory Overview page, create the labels.

      1. Navigate to the code "CaptionLabel": "$(L, z_purchaseRequisition_label)"

        Hint

        You can use Ctrl+. to view the quick fixes option. Using the quick fix you can directly create an entry in the i18n without explicitly navigating to the file via explorer.

      2. Create an entry in i18n.properties (i18n_en.properties). The new entry will always be created at the end.

        Hint

        Keeping all your changes at the end of the file allows you to track the changes. Also helpful to migrate changes during upgrade.

    Task 2: Create a Rule to Display the Count in KPI

    Steps

    1. Create folders ZSAPComponent > Rules > Inventory > Overview.

      1. Perform the required steps as required in an earlier exercise.

    2. Create a new rule Z_PurchaseRequisitionKPIItemsCount.js with the following code:

      Code Snippet
      1234
      export default function Z_PurchaseRequisitionKPIItemsCount(context) { return context.count('/SAPAssetManager/Services/AssetManager.service', 'Z_##_PurchaseRequisitions', '').then((count) => { return count;}); }
      1. Perform the required steps as required in an earlier exercise.

    Task 3: Create a List Page

    Steps

    1. Create a folder ZSAPComponentPagesInventoryZ_PurchaseRequsition.

      1. Perform the required steps as required in an earlier exercise.

    2. Create a new in MDK Page with name Z_PurchaseRequisitionList.page.

      1. Right-click on ZSAPComponentPagesZ_PurchaseRequsition.

      2. Choose New MDK Page.

      3. In the Page creation wizard, select Section Page and choose Next.

      4. Enter the page name Z_PurchaseRequisitionList (without .page) and choose Next followed by Finish in the Confirmation window.

    3. Add Controls and configure the PurchaseRequisitionList page.

      Use the following data:

      FieldValue
      Service/ZSAMComponent/Services/AssetManager.service
      EntitySetZ_##_PurchaseRequisitions
      QueryOptions$orderby=PurchasingReq,RequisnItem

      1. Double-click on the newly created page PurchaseRequisitionList to open it in the layout editor (if not already open).

      2. Select the Controls tab.

      3. Enter the term Object Table in the search field and choose Enter.

      4. From the search results, drag the Object Table on to the PurchaseRequisitionList page.

      5. In the right pane Properties window, under the Target section use the dropdown and choose the values from the preceding table.

        Note

        If you have not synced the service before, do it now. Note that we only perform this on the AssetManager.service in ZSAMComponent. We will not change the standard SAPAssetManager project.

        In the Property tab, use the dropdown options to choose values.
    4. Update the properties in the Appearance section.

      Use the following data:

      PropertyValue
      CaptionPurchase Requisitions
      NameZ_PurchaseRequisitionList
      Description{ShortText}
      Subhead{ShortText}
      Title{PurchasingReq} - {RequisnItem}
      Footnote{Plant} {StoageLocation}
      StatusText{Quantity} {UOM}
      SubstatusText{ValuationPrice} {PriceUnit}
      1. Perform the required steps as described earlier.

    Task 4: Update CIM File

    Steps

    1. Add an entry in the CIM file for the InventoryOverview Page. The CIM is located in the SAPAssetManager project.

      1. Perform the required steps as described earlier. Use the following code:

        Code Snippet
        12345
        { "Source": "/ZSAPComponent/Pages/Inventory/InventoryOverview.page", "Target": "/SAPAssetManager/Pages/Inventory/InventoryOverview.page" }

    Task 5: Deploy the App to SAP BTP (MDK Deploy) and Test

    Steps

    1. Deploy the app to SAP BTP (MDK Deploy) and test.

      1. Right-click on the SAPAssetManagerApplication.app and choose the MDK:Deploy command from the context menu to deploy the mobile app.

        Screenshot showing the Purchase Requisitions tab.
      2. Perform some tests. To view the Purchase Requisitions, go to Profile SettingsSwitch PersonaChoose Inventory Clerk.

    Task 6: Optional: Add Navigation to Account Assignment

    • Repeat the preceding steps to create another section page with object table control for displaying the Purchase Requisition Assignment.
    • Create a Navigation Action from Purchase Requisitions (onPress Event) to display the Account Assignment.

    Create Purchase Requisition (Part 1: Back-end)

    Note

    Use the transaction SE24 and there the reference class handler /MERP/CL_MM_PURCHASE_REQ_OD to create your copy Zxxx files. The code snippets provided in this handbook are examples for your reference only. Copy the required coding from the reference class.

    Note

    The steps below are giving a guide so that you can perform this exercise in your own system landscape.

    Task 1: Update the oMDO Class Handler: Development Tasks

    Steps

    1. Update the oMDO Class for the previous created purchase requisition ZIAM_##_CL_MM_PURCHASE_REQ.

      1. Log in to the SAP system and navigate to transaction code SE24.

      2. Enter ZIAM_##_CL_MM_PURCHASE_REQ.

      3. Choose the Change button.

    2. Redefine the method /mfnd/if_core_omdo_handler-create with the following code:

      Code Snippet
      12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
      METHOD /mfnd/if_core_omdo_handler~create. super->create( CHANGING cref_omdo_data = cref_omdo_data ). REFRESH: tab_preq_items, tab_preq_item_texts, tab_preq_acc_assignment, tab_preq_header_text, tab_preq_limits, tab_preq_contract_limits, tab_preq_services, tab_preq_srv_accass_values, tab_preq_services_text, tab_preq_addrdelivery, tab_extensionin. TRY. LOOP AT cref_omdo_data->tab_omdo_entity_input ASSIGNING FIELD-SYMBOL(<entity_input>). CASE <entity_input>-tech_entity_type. WHEN const_preq_entity. convert_input_preq( EXPORTING iref_input_data = <entity_input>-request_data IMPORTING ev_error = DATA (ev_error ) ). WHEN const_preq_note_entity. convert_input_preq_notes( EXPORTING iref_input_data = <entity_input>-request_data IMPORTING ev_error = DATA(lv_error ) ). ENDCASE. IF ev_error = abap_true. RETURN. ENDIF. ENDLOOP. IF lv_error IS INITIAL. call_bapi_requisition_create( IMPORTING ev_banfn = DATA(lv_banfn_out) CHANGING cref_omdo_data = cref_omdo_data ). build_preq_output_data( EXPORTING iv_banfn = lv_banfn_out CHANGING cref_omdo_data = cref_omdo_data ). ENDIF. CATCH /merp/cx_core_exception_gen INTO DATA(lref_exception) ##CATCH_ALL. message = lref_exception->get_text( ). logger->logerror( iv_message = message iv_source = source iv_user_guid = user_guid iref_return_tab = cref_omdo_data->dref_return ). RETURN. ENDTRY. ENDMETHOD.
      1. Choose the Methods Tab.

      2. Choose Find and search for the method CREATE.

      3. Choose Redefine.

      4. Clear the code within the method and copy paste the given code into the method.

      5. Check the syntax with Ctrl + F2.

      6. Choose Save.

      7. Do not forget to activate the method by choosing Activate.

    3. Create the method CALL_BAPI_REQUISITION_CREATE with the following code:

      Code Snippet
      1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
      METHOD call_bapi_requisition_create. CLEAR: ev_banfn. "Insert Start S4MERP SP11 bugid S4MOBADDON-2931 DATA: lv_skip_items_with_error TYPE bapimmpara-selection, lv_automatic_source TYPE bapimmpara-selection, ls_range TYPE /mfnd/core_range_str, lt_bapireturn TYPE STANDARD TABLE OF bapireturn, ls_return TYPE bapiret2, ls_thead TYPE thead. "oo Reference variables DATA: lref_exception TYPE REF TO cx_root. READ TABLE str_dof_filter_vals-skip_item_with_error->* INTO ls_range INDEX 1. IF sy-subrc = 0. lv_skip_items_with_error = ls_range-low. ENDIF. READ TABLE str_dof_filter_vals-automatic_source->* INTO ls_range INDEX 1. IF sy-subrc = 0. lv_automatic_source = ls_range-low. ENDIF. TRY. CALL FUNCTION 'BAPI_REQUISITION_CREATE' EXPORTING skip_items_with_error = lv_skip_items_with_error automatic_source = lv_automatic_source IMPORTING number = ev_banfn TABLES requisition_items = tab_preq_items requisition_account_assignment = tab_preq_acc_assignment requisition_item_text = tab_preq_item_texts requisition_limits = tab_preq_limits requisition_contract_limits = tab_preq_contract_limits requisition_services = tab_preq_services requisition_srv_accass_values = tab_preq_srv_accass_values return = lt_bapireturn requisition_services_text = tab_preq_services_text requisition_addrdelivery = tab_preq_addrdelivery extensionin = tab_extensionin. APPEND LINES OF lt_bapireturn TO cref_omdo_data->dref_return->*. LOOP AT lt_bapireturn ASSIGNING FIELD-SYMBOL() WHERE type = 'E' OR type = 'A'. APPEND TO cref_omdo_data->dref_return->*. CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'. ENDLOOP. IF sy-subrc <> 0. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING wait = abap_true IMPORTING return = ls_return. ENDIF. CATCH /merp/cx_core_exception_gen INTO lref_exception. "#EC CATCH_ALL message = lref_exception->get_text( ). logger->logerror( iv_message = message iv_source = source iv_user_guid = user_guid iref_return_tab = cref_omdo_data->dref_return ). ENDTRY. ENDMETHOD.
      1. Perform the steps as described in the preceding step.

    4. Create the method BUILD_PREQ_OUTPUT_DATA with the following code:

      Code Snippet
      12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
      METHOD build_preq_output_data. FIELD-SYMBOLS: <data> TYPE any, <banfn> TYPE any, <bnfpo> TYPE any, <objkey> TYPE any, <textid> TYPE any. DATA: lt_preq TYPE gtyp_preq_key_tab, ls_preq TYPE gtyp_preq_key_str. IF iv_banfn IS NOT INITIAL. SELECT banfn bnfpo FROM eban INTO TABLE lt_preq WHERE banfn = iv_banfn. READ TABLE lt_preq INTO ls_preq INDEX 1. "#EC CI_NOORDER LOOP AT cref_omdo_data->tab_omdo_entity_input ASSIGNING FIELD-SYMBOL(). IF -tech_entity_type = const_preq_entity. READ TABLE lt_preq INTO ls_preq INDEX 1. "#EC CI_NOORDER IF sy-subrc = 0. ASSIGN -request_data->* TO . ASSIGN COMPONENT 'BANFN' OF STRUCTURE TO . CHECK sy-subrc = 0. ASSIGN COMPONENT 'BNFPO' OF STRUCTURE TO . CHECK sy-subrc = 0. <banfn> = ls_preq-banfn. <bnfpo> = ls_preq-bnfpo. DELETE lt_preq INDEX 1. "#EC CI_NOORDER ENDIF. ENDIF. IF <entity_input>-tech_entity_type = const_preq_note_entity. IF ls_preq-banfn IS NOT INITIAL. ASSIGN <entity_input>-request_data->* TO <data>. ASSIGN COMPONENT 'BANFN' OF STRUCTURE <data> TO <banfn>. CHECK sy-subrc = 0. ASSIGN COMPONENT 'OBJKEY' OF STRUCTURE <data> TO <objkey>. CHECK sy-subrc = 0. ASSIGN COMPONENT 'TEXT_ID' OF STRUCTURE <data> TO <textid>. CHECK sy-subrc = 0. <banfn> = ls_preq-banfn. <textid> = 'B01'. CONCATENATE ls_preq-banfn ls_preq-bnfpo INTO <objkey>. ENDIF. ENDIF. cref_omdo_data->add_omdo_output_single( iv_tech_entity_type = <entity_input>-tech_entity_type iv_request_no = <entity_input>-request_no iref_data = <entity_input>-request_data ). ENDLOOP. ENDIF. ENDMETHOD. "#EC CI_CYCLO
      1. Perform the steps as described in Step 2.

    Create Purchase Requisition (Part-2: MDK Metadata)

    Note

    The steps below are giving a guide so that you can perform this exercise in your own system landscape.

    Task 1: Enhance the Inventory Overview Page to Create Purchase Requisitions

    In this task, we enhance the Inventory Overview page to add an action for creating the Purchase Requisition.

    Steps

    1. Open the ZSAMComponent Inventory Overview page.

      1. In the Explorer view, navigate to the ZSAMComponent Inventory Overview page.

      2. Right click and from the menu choose Open WithCode Editor/ZSAPComponent/Pages/Inventory/InventoryOverview.page.

    2. In the ActionBar section and change the onPress code form SAPAssetManager to ZSAPComponent.

      1. In the Code Editor view page, navigate to the ActionBar section and change the code as shown after this:

        From:

        Code Snippet
        123
        "OnPress": "/SAPAssetManager/Actions/Inventory/CreateUpdateDelete/CreateDocumentPopover.action"
        to
        Code Snippet
        12
        "OnPress": "/ZSAPComponent/Actions/Inventory/CreateUpdateDelete/CreateDocumentPopover.action"

    Task 2: Enhance the Action for Triggering Create Purchase Requisition

    Steps

    1. Create the folder /ZSAPComponent/Actions/Inventory/CreateUpdateDelete.

      1. Create a folder as described in earlier exercises.

    2. Copy the file CreateDocumentPopover.action from /SAPAssetManager/Actions/Inventory/CreateUpdateDelete to / /ZSAPComponent/Actions/Inventory/CreateUpdateDelete/.

      1. The copy procedure is described in an earlier exercise.

    3. Extend CreateDocumentPopover.action.

      1. Right-click and open the CreateDocumentPopover.action in the Code Editor.

      2. Add the following code to after the Physical Inventory creation action.

        Code Snippet
        12345
        { "Title": "$(L, z_add_purchase_requisition)", "OnPress": "/ZSAPComponent/Rules/Inventory/Z_PurchaseRequisition/SetPurchaseRequisitionCreate.js" }
    4. Create an entry in the i18n.properties for the Z_add_purchase_requisition.

      1. Place the cursor on the Z_add_purchase_requisition and simultaneously choose the two keys: Ctrl and the Period (.) (in the following displayed as Ctrl +.).

      2. Choose MDK: Create i18n entry for key: z_add_purchase_requisition and add the text Add Purchase Requisition.

    Task 3: Create a Rule and Action to Navigate to the Purchase Requisition Create Page

    Steps

    1. Create the rule SetPurchaseRequisitionCreate.js.

      1. Place the cursor on the SetPurchaseRequisitionCreate.js and use Ctrl +. to create the rule.

      2. Open the rule and add the following code:

        Code Snippet
        1234567891011121314151617
        import libCom from '../../../../SAPAssetManager/Rules/Common/Library/CommonLibrary'; /** * Describe this function... * @param {IClientAPI} context */ export default function SetPurchaseRequisitionCreate(context) { libCom.setStateVariable(context, 'Temp_PurchaseReqReadLink',''); libCom.setStateVariable(context, 'Z_PurchaseRequisitionReturnToList', true); libCom.setStateVariable(context, 'Local_PurchaseReq',''); libCom.setStateVariable(context, 'PhysicalInventoryLocalFiscalYear', new Date().getFullYear().toString()); //Navigate Action to create page return context.executeAction('/ZSAPComponent/Actions/Inventory/Z_PurchaseRequisition/Z_PurchaseRequisitionCreateNav.action'); }
    2. Create the action Z_PurchaseRequisitionCreateNav.action.

      1. While in the SetPurchaseRequisitionCreate.js Rule, place cursor on the Z_PurchaseRequisitionCreateNav.action and use Ctrl +. to create a Navigation Action.

        This will also create a new folder in the Actions.

      2. Right click on the Z_PurchaseRequisitionCreateNav.action and open in Code Editor and enter the following code:

        Note

        The statement ModalPage opens the new Page as a model.

        Code Snippet
        123456
        { "_Type": "Action.Type.Navigation", "PageToOpen": "/ZSAPComponent/Pages/Inventory/Z_PurchaseRequisition/Z_PurchaseRequisitionCreate.page", "ModalPage": true }

    Task 4: Create the Purchase Requisition Create Page

    Steps

    1. Create the MDK Page Z_PurchaseRequisitionCreate.page.

      1. While in the Z_PurchaseRequisitionCreateNav.action, place the cursor on the Z_PurchaseRequisitionCreate.page and use Ctrl +. to create a Section MDK Page.

      2. When prompted to choose Page Type, choose the Section Page.

      3. Right click and open the page in Code Editor and insert the following code.

        Code Snippet
        123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
        { "Caption": "$(L,z_PurchaseRequisitionCreate)", "ActionBar": { "Items": [ { "Position": "left", "SystemItem": "Cancel", "OnPress": "/SAPAssetManager/Rules/Common/CheckForChangesBeforeClose.js" }, { "Position": "right", "SystemItem": "$(PLT,'Done','')", "Text": "$(L,apply)", "OnPress": "/ZSAPComponent/Actions/Inventory/Z_PurchaseRequisition/Z_PurchaseRequisitionCreate.action" } ] }, "Controls": [ { "Sections": [ { "Controls": [ { "_Name": "PurchasingReq", "Caption": "$(L,z_purchaseRequisitionID)", "_Type": "Control.Type.FormCell.SimpleProperty", "IsEditable": false, "Value": "%000000001" }, { "_Name": "RequisnItem", "Caption": "$(L,z_purchaseRequisitionItem)", "_Type": "Control.Type.FormCell.SimpleProperty", "IsEditable": true, "Value": "{RequisnItem}", "KeyboardType": "Number" }, { "IsEditable": true, "Value": "{ShortText}", "KeyboardType": "Number", "_Name": "ShortText", "Caption": "$(L,z_ShortText)", "_Type": "Control.Type.FormCell.SimpleProperty" } ] }, { "Controls": [ { "_Name": "PlantLstPkr", "_Type": "Control.Type.FormCell.ListPicker", "Caption": "$(L,plant)", "AllowMultipleSelection": false, "AllowDefaultValueIfOneItem": false, "IsPickerDismissedOnSelection": true, "IsSearchCancelledAfterSelection": true, "Search": { "Enabled": true, "Delay": 500, "MinimumCharacterThreshold": 3, "Placeholder": "$(L,search)", "BarcodeScanner": true }, "IsEditable": true, "PickerItems": { "DisplayValue": "{{#Property:Plant}} - {{#Property:PlantDescription}}", "ReturnValue": "{Plant}", "Target": { "EntitySet": "Plants", "Service": "/SAPAssetManager/Services/AssetManager.service", "QueryOptions": "$orderby=Plant asc" } } }, { "_Name": "StorageLocationPicker", "_Type": "Control.Type.FormCell.ListPicker", "Caption": "$(L,storage_location)", "AllowEmptySelection": true, "AllowMultipleSelection": false, "IsPickerDismissedOnSelection": true, "AllowDefaultValueIfOneItem": true, "Value": "{StorageLocation}", "IsEditable": true, "IsSelectedSectionEnabled": false, "PickerItems": { "DisplayValue": "{{#Property:StorageLocation}} - {{#Property:StorageLocationDesc}}", "ReturnValue": "{StorageLocation}", "Target": { "EntitySet": "StorageLocations", "QueryOptions": "$orderby=Plant asc", "Service": "/SAPAssetManager/Services/AssetManager.service" } }, "PickerPrompt": "$(L,select_single_item)" }, { "_Name": "MatrialListPicker", "_Type": "Control.Type.FormCell.ListPicker", "Caption": "$(L,material_number)", "AllowMultipleSelection": false, "AllowDefaultValueIfOneItem": true, "IsPickerDismissedOnSelection": true, "IsSearchCancelledAfterSelection": true, "Search": { "Enabled": true, "Delay": 500, "MinimumCharacterThreshold": 1, "Placeholder": "$(L,search)", "BarcodeScanner": true }, "Value": "{Material}", "IsEditable": true, "PickerItems": { "ObjectCell": { "PreserveIconStackSpacing": false, "Title": "{{#Property:MaterialNum}} - {{#Property:Description}}" //"Subhead": "{Plant}" //"Footnote": "{StorageLocation} - {StorageLocationDesc}", }, "ReturnValue": "{MaterialNum}", "Target": { "EntitySet" : "Materials", //"EntitySet": "MaterialSLocs", "Service" : "/SAPAssetManager/Services/AssetManager.service", "QueryOptions" : "$orderby=MaterialNum" } } }, { "_Name": "PurchasngOrgPkr", "_Type": "Control.Type.FormCell.ListPicker", "Caption": "$(L,z_PurchasngOrg)", "AllowMultipleSelection": false, "AllowDefaultValueIfOneItem": false, "IsPickerDismissedOnSelection": true, "IsSearchCancelledAfterSelection": true, "Search": { "Enabled": true, "Delay": 500, "MinimumCharacterThreshold": 3, "Placeholder": "$(L,search)", "BarcodeScanner": true }, "IsEditable": true, "PickerItems": { "DisplayValue": "{{#Property:PurchasingOrg}} - {{#Property:PlantDescription}}", "ReturnValue": "{PurchasingOrg}", "Target": { "EntitySet": "Z_##_PurchaseOrganizations", "Service": "/ZSAPComponent/Services/AssetManager.service", "QueryOptions": "$orderby=PurchasingOrg asc" } } }, { "_Name": "PurchGroup", "Caption": "$(L,z_PurchGroup)", "Value": "001", "IsEditable": true, "IsVisible": true, "_Type": "Control.Type.FormCell.SimpleProperty" }, { "_Name": "Quantity", "Caption": "$(L,quantity)", "IsEditable": true, "KeyboardType": "Number", "Value": "{Quantity}", "_Type": "Control.Type.FormCell.SimpleProperty" }, { "_Name": "UOMListPicker", "_Type": "Control.Type.FormCell.ListPicker", "Caption": "$(L,uom)", "AllowMultipleSelection": false, "AllowDefaultValueIfOneItem": true, "IsPickerDismissedOnSelection": true, "IsSearchCancelledAfterSelection": true, "Search": { "Enabled": true, "Delay": 500, "MinimumCharacterThreshold": 1, "Placeholder": "$(L,search)", "BarcodeScanner": true }, "Value": "{UOM}", "IsEditable": false, "PickerItems": { "ReturnValue": "{BaseUOM}", "DisplayValue": "{BaseUOM}", "Target": { "EntitySet" : "MaterialUOMs", "Service" : "/SAPAssetManager/Services/AssetManager.service", "QueryOptions": "$orderby=UOM" } } } ] }, { "Controls": [ { "_Name": "DeliveryDatePicker", "Caption": "$(L,z_DeliveryDate)", "_Type": "Control.Type.FormCell.DatePicker", "DateTimeEntryMode" : "date", "Mode" : "Date", "Value": "{DeliveryDate}", "IsEditable": false }, { "_Name": "DeliveryDateCategory", "Value": "1", "IsEditable": false, "IsVisible": false, "_Type": "Control.Type.FormCell.SimpleProperty" }, { "_Name": "DocCategory", "Caption": "$(L,z_DocCategory)", "Value": "B", "IsEditable": false, "IsVisible": true, "_Type": "Control.Type.FormCell.SimpleProperty" }, { "_Name": "DocType", "Caption": "$(L,z_DocType)", "Value": "NB", "IsEditable": false, "IsVisible": true, "_Type": "Control.Type.FormCell.SimpleProperty" }, { "_Name": "PriceUnit", "Value": "1", "IsEditable": false, "IsVisible": true, "_Type": "Control.Type.FormCell.SimpleProperty" }, { "_Name": "ValuationPrice", "Caption": "$(L,z_ValuationPrice)", "Value": "{ValuationPrice}", "IsEditable": true, "IsVisible": true, "_Type": "Control.Type.FormCell.SimpleProperty", "AlternateInput": "Barcode" } ] } ], "_Name": "FormCellContainer", "_Type": "Control.Type.FormCellContainer" } ], "_Type": "Page", "Name": "Z_PurchaseRequisitionCreate", "PrefersLargeCaption": true, "OnReturning": "/SAPAssetManager/Rules/Inventory/PhysicalInventory/Count/PhysicalInventoryCountUpdateOnReturning.js" }
    2. Create the following text strings/labels in i18n.properties:

      Entry
      z_purchaseRequistion_label=Purchase Requisitions
      z_add_purchase_requisition=Add Purchase Requisition
      z_PurchaseRequisitionCreate=Create Purchase Requisition
      z_purchaseRequisitionID=Purchase Requisition
      z_purchaseRequisitionItem=Item
      z_ShortText=Short Text
      z_PurchasngOrg=Purchase organization
      z_PurchGroup=Purchase Group
      z_DeliveryDate=Delivery Date
      z_DocCategory=Document Category
      z_DocType=Document Type
      z_ValuationPrice=Price
      1. Perform the required steps as described in previous exercises.

    Task 5: Create OnPress Action to Check for Required Field

    Steps

    1. Use the code to create a check for the required field.

      1. While in the Z_PurchaseRequisitionCreate.page navigate to the OnPress Action. This is the code:

        Code Snippet
        12
        "OnPress": "/ZSAPComponent/Actions/Inventory/Z_PurchaseRequisition/Z_PurchaseRequisitionCreateRequired.action"
      2. Place the cursor on the action and use Ctrl +. to create the action for checking the required fields.

      3. Use the following code:

        Code Snippet
        123456789101112131415161718192021
        { "OnFailure": "/SAPAssetManager/Rules/Common/UpdateRequiredFailed.js", "OnSuccess": "/ZSAPComponent/Rules/Inventory/Z_PurchaseRequisition/Z_PurchaseRequisitionCreateOnCommit.js", "RequiredFields": [ "PurchasingReq", "RequisnItem", "ShortText", "MatrialListPicker", "PlantLstPkr", "Quantity", "ValuationPrice", "DocCategory", "DocType" ], "_Type": "Action.Type.CheckRequiredFields", "ShowActivityIndicator": true, "ActivityIndicatorText" : " " }

    Task 6: Create Z_PurchaseRequisitionCreateOnCommit Rule to Validate the Fields and Call Commit Action

    Steps

    1. Create a Z_PurchaseRequisitionCreateOnCommit rule to validate the fields and call the commit action.

      1. Use the following code:

        Code Snippet
        123456789101112131415161718192021222324252627282930
        import commonLib from '../../../../SAPAssetManager/Rules/Common/Library/CommonLibrary'; import Logger from '../../../../SAPAssetManager/Rules/Log/Logger'; export default function Z_PurchaseRequisitionCreateOnCommit(context) { let onCreate = commonLib.IsOnCreate(context); return validateData(context).then(valid => { if (valid) { if (onCreate) { let plant = context.getPageProxy().getControl('FormCellContainer').getControl('PlantLstPkr').getValue()[0].ReturnValue; commonLib.setStateVariable(context, 'Z_PurchaseRequisitionPlant', plant); let storageLocation = context.getPageProxy().getControl('FormCellContainer').getControl('StorageLocationPicker').getValue()[0].ReturnValue; commonLib.setStateVariable(context, 'Z_PurchaseRequisitionStorageLocation', storageLocation); return context.executeAction('/ZSAPComponent/Actions/Inventory/Z_PurchaseRequisition/Z_PurchaseRequisitionCreate.action').then(() => { return context.executeAction('/SAPAssetManager/Actions/Page/ClosePage.action'); }).catch((error)=>{ Logger.error('PurchaseRequisition', 'PurchaseRequisition.create error: ${error}'); }); } else { //Update NOT Supported } } return false; //Validation failed }) }

    Task 7: Create the Purchase Requisition Action

    Screenshot of the purchase requisition action.

    Steps

    1. Create the Purchase Requisition Action.

      1. Use the following code:

        Code Snippet
        12345678910111213141516171819202122232425262728293031323334
        { "_Type": "Action.Type.ODataService.CreateEntity", "ShowActivityIndicator": true, "Target": { "Service": "/ZSAPComponent/Services/AssetManager.service", "EntitySet": "Z_##_PurchaseRequisitions" }, "Properties": { "PurchasingReq": "#Control:PurchasingReq/#Value", "RequisnItem": "#Control:RequisnItem/#Value", "CreatedBy": "/SAPAssetManager/Rules/MobileStatus/GetSAPUserId.js", "DeliveryDate": "#Control:DeliveryDatePicker/#Value", "DeliveryDateCategory": "#Control:DeliveryDateCategory/#Value", "DocCategory": "#Control:DocCategory/#Value", "DocType": "#Control:DocType/#Value", "Material": "#Control:MatrialListPicker/#SelectedValue", "Plant": "#Control:PlantLstPkr/#SelectedValue", "PriceUnit": "#Control:PriceUnit/#Value", "PurchGroup": "#Control:PurchGroup/#Value", "PurchasngOrg": "#Control:PurchasngOrgPkr/#SelectedValue", "Quantity": "#Control:Quantity/#Value", "RequisnDate": "#Control:DeliveryDatePicker/#Value", "ShortText": "#Control:ShortText/#Value", "StorageLocation": "#Control:StorageLocationPicker/#SelectedValue", "UOM": "#Control:UOMListPicker/#SelectedValue", "ValuationPrice": "#Control:ValuationPrice/#Value" }, "Headers": { "OfflineOData.RemoveAfterUpload": "true", "OfflineOData.TransactionID": "%000000001" } }

    Task 8: Deploy the App to BTP (MDK Deploy) and Test

    Steps

    1. Deploy the app to SAP BTP (MDK Deploy) and test.

      1. Right-click on the SAPAssetManagerApplication.app and from the context menu choose MDK:Deploy to deploy the Mobile App.

        Choose the plus icon, then select Add Purchase Requisition.