Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
manasi_b
Explorer


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 😊.
7 Comments
Labels in this area