Skip to Content
Technical Articles

PPM Financial Planning – Update FIN_PLAN Values using API: How-to guide

In the picture: PPM > Portfolio Management > Financial Planning(Picture Courtesy: SAP)

 

My project had a requirement to add up actual values(actual and actual-manual) and copy to forecast values in the Financial Planning of the PPM Module. Even though this sounds very simple, anyone who knows PPM tables knows that it is more than what meets the eye.

I struggled a lot to find an apt way of achieving this. I tried many other processes like Function Module(FM) /RPM/FIN_PLAN_SAVE_DB. The problem with this FM was that all entries in the plan table belonging to a group had to be passed to this FM even when we had to update just one record in that group. I also explored the BADIs /RPM/EX_FIN_B_PLAN_BADI, /RPM/EX_FIN_PLAN, /RPM/FIN_CAP_PLAN . But I wanted something that can be called within an FM which updates the /RPM/FIN_PLAN table with plan details. Finally, while debugging I stumbled upon the API /rpm/cl_fin_cap_planning_api. This API was best suited for my requirement as I only had to pass the changed entry and it internally selects the rest of the plan entries in the group. I spent a lot of researching how to make use of this API specially to know how to pass the context to the API. I am writing this blog post to help my fellow developers.

The steps described in this blog post can also be used to update Capacity Planning tables.

Requirement: There are 2 views to capture actual cost – Actual(comes from ECC) and Actual-Manual(entered manually). The requirement is that the Forecast view should be calculated by adding the two costs – Actual and Actual-Manual.

This blog post is a step-by-step how-to guide to achieve this objective.

Steps:

  1. Get guid from table /RPM/ITEM_D for the external_id in the input table(IT_PROJ)
  2. Get required fields into 1 table using join from /rpm/item_d /rpm/fin_cat, /rpm/fin_group /rpm/fin_plan
  3. Add the values of actual and actual-manual costs of corresponding months and categories
  4. Update the forecast costs using API. Use get_plan_info method to pass the context**. Call initialize_planning method and finally fin_groups_modify  to update values. The API is well designed in the sense that only the changed fin_plan entries need to be passed and the API handles the rest.

** very crucial part..took me a while to figure out how to pass the context

  1. Very important to call the cl_inm_ppm_services=>save to commit work.
  2. Capture the messages and display.

I have given the required code of the RFC FM below. The FM takes one or more External_id(s) of the Project(/RPM/ITEM_D-EXTERNAL_ID) as the input, calculates the Forecast view and in turn updates the tables(/RPM/FIN_PLAN,  /RPM/FIN_GROUP) for the same.

FM Interface:

 

FUNCTION z_fin_calc .

 ………………………….

  "reference(s)
  DATA: lo_fin_cap_planning_api TYPE REF TO /rpm/cl_fin_cap_planning_api.

  "field-symbols
  FIELD-SYMBOLS: <fs_fin_plan>      TYPE x_fin_planf,
                 <fs_msg>           TYPE /rpm/ts_messages.

  "select projects and process
  ……………………………………………………..

  "get api reference
  CALL METHOD /rpm/cl_fin_cap_planning_api=>get_instance
    RECEIVING
      rr_instance = lo_fin_cap_planning_api.

  IF lo_fin_cap_planning_api IS BOUND.

    "loop projects
    LOOP AT tb_item_d INTO s_item_d.

      CLEAR: tb_fin_group_api[], tb_fin_plan_api.

      "populate context
      CLEAR s_context.
      s_context-portfolio_guid = s_item_d-portfolio_guid.
      s_context-parent_type = k_parent_type. "'RIH'.
      s_context-parent_guid = s_item_d-guid.
      s_context-object_type = k_object_type."'RIH'.
      s_context-object_guid = s_item_d-guid.

      "get plan info
      CLEAR: var_subrc, s_plan_info.
      CALL METHOD lo_fin_cap_planning_api->get_plan_info
        EXPORTING
          is_context   = s_context
*         iv_language  =
          iv_fin_cap   = k_fin_cap "1
        IMPORTING
          es_plan_info = s_plan_info
          et_msgs      = tb_msgs[]
          ev_rc        = var_subrc.

      APPEND LINES OF tb_msgs TO tb_msgs_item.
      CLEAR tb_msgs[].

      "pass context
      CALL METHOD lo_fin_cap_planning_api->initialize_planning
        EXPORTING
          is_context        = s_context
          iv_hierarchy_type = k_hierarchy_type
          iv_fin_cap        = k_fin_cap "1
*         iv_language       =
          it_filter_data    = tb_filter_data[]
          is_plan_info      = s_plan_info
*         iv_portfolio_type =
        IMPORTING
          et_msgs           = tb_msgs[]
*         es_mode           =                                                                                                                                                                *
        .
……………………………………………………..

        "for every group
        AT END OF guid_g ##loop_atb_ok.
          "only if plan table is filled
          "update fin plan
          IF tb_fin_plan_api[] IS NOT INITIAL.
            "call api
            CALL METHOD lo_fin_cap_planning_api->fin_groups_modify
              EXPORTING
                iv_category_guid  = var_cat_guid
                it_fin_groups     = tb_fin_group_api[]
                it_fin_plan       = tb_fin_plan_api[]
                iv_hierarchy_type = k_hierarchy_type
                iv_language       = k_language
                is_plan_info      = s_plan_info
              IMPORTING
                ev_rc             = var_subrc
                et_msgs           = tb_msgs[].

            APPEND LINES OF tb_msgs TO tb_msgs_group.
            CLEAR tb_msgs[].
            "save
            CALL METHOD cl_inm_ppm_services=>save(
              EXPORTING
                iv_check_only = /rpm/cl_co=>sk_false
              IMPORTING
                et_messages   = tb_msgs[]
                ev_rejected   = var_rejected ).

            APPEND LINES OF tb_msgs TO tb_msgs_group.
            CLEAR tb_msgs[].

            "append project and group external ID
            UNASSIGN <fs_msg>.
            LOOP AT tb_msgs_group ASSIGNING <fs_msg>.
              <fs_msg>-objectid = s_item_d-external_id.
            ENDLOOP.
            UNASSIGN <fs_msg>.

            APPEND LINES OF tb_msgs_group TO etb_msgs.
            CLEAR tb_msgs_group[].
          ENDIF.
          CLEAR: tb_fin_group_api[], tb_fin_plan_api[], s_fin_group_api.
        ENDAT.
      ENDLOOP.

    ENDLOOP.

  ENDIF.


ENDFUNCTION.

 

To summarize, you learnt how to make use of std. SAP API /rpm/cl_fin_cap_planning_api to update /RPM/FIN_PLAN and /RPM/FIN_GROUP tables. Did this blog post help you, or answer at least some of your questions. Please share your feedback or thoughts in a comment 😊.

Be the first to leave a comment
You must be Logged on to comment or reply to a post.