An alert is a notification of the issue or deviation in project happening in project compared to plan. SAP Commercial Project Management defines 14 different type of alert within standard as shown below as of release 1709. Additional alerts also can be configured with minimal development effort. This document describes enhancing alerts with a custom alert.
CPM Fiori apps draws user attention to deviation effecting project health by alert. Alert helps in taking corrective action and prevent delays in the processing of critical situations, because the time between discovering and responding to such situations is reduced considerably
Alert:
Below screenshot provides SAP Commercial Project Management 14 different type of alert within standard of release 1709.
Following Steps Guide you to add custom define alert in SAP CPM. For easy understanding, I'm going to guide to add alert called "Unapproved CR Cost". This alert user on amount of cost that are not approved from change request.
Step1:
Create an active BAdI implementation for the alert ID you are about to create. To do so, go to Customizing by choosing
SAP Commercial Project Management > Master Data > Business Add-Ins > BAdI: Master Project Alerts
Step 2:
Assign alert ID value to implementation as show below:
Step 3:
Implementation classes in BADI:
Step 4:
Define data type required as shown below in implementation class:
Step 5:
Currency as unit to represent the value which is coded for "Euro":
Step 6:
Logic to fetch Alert value of unapproved CR is at end of the document.
Step 7:
SAP Commercial Project Management > Master Data >Define Alerts
Alert ID: To identify the user defined alert, normally started by “Z” For example “ZUPCRV” which is Total value of unapproved change request
Description: Elaborates alert and briefs the background of alert.
Step 8:
SAP Commercial Project Management > Master Data >Master Project -> make Setting for Master Projects
Defined Alerts are assigned to Master Project by Master Project Type by
Choose Master Project Type and double Click on “Assign Alert ID to Master Project Types"
Next screen allows to add defines Alert by click on button .
Note: Only added Alerts will be made available for the user to view in Cross Project View and Workspace against Master Project.
Step 9:
Condition can be defined for each alert by click on “Maintain Alert Condition” as shown below, which serves as default condition for given alert under Master Project Type.
User can define his own condition by updating below information:
Severity ID: Specifies the priority or impact or intensity that Alert has on project
Condition: Gives the option for user to specify value or range and restricted range for the given severity under Alert condition.
Lower and Upper Limit: Allows to enter lower and upper value for the condition specifying range.
Step 10:
Configured Alert displayed as below in cross project view:
Logic:
METHOD /cpd/if_pws_alert~execute.
TYPES: BEGIN OF ly_data,
issue_id TYPE char20,
alt_id TYPE char20,
plan_id TYPE /cpd/pfp_plan_id,
END OF ly_data.
DATA: ls_data TYPE ly_data.
DATA lv_plan_header_id TYPE /cpd/pfp_plan_id.
DATA: lt_data TYPE TABLE OF ly_data.
* * Data Declaration
DATA : lv_version_id TYPE /cpd/pfp_version_id,
lv_version_type TYPE /cpd/pfp_ver_type_id,
lt_plan_version TYPE /cpd/t_pfp_plan_version,
ls_plan_version TYPE /cpd/s_pfp_plan_version,
lo_data TYPE REF TO if_bs_anly_list_data,
lv_subrc TYPE sy-subrc,
lt_query TYPE bsanly_t_query,
lo_selection TYPE REF TO if_bs_anly_selection,
lt_def TYPE rsr_t_variable_definition,
lt_selection TYPE bsanly_ts_selection,
ls_selection TYPE bsanly_s_selection,
* ls_cr_cra LIKE LINE OF it_cr_cra,
lt_columns TYPE bsanly_ts_alv_col,
ls_columns LIKE LINE OF lt_columns,
lr_t_data TYPE REF TO data,
lt_message TYPE bsanly_t_message,
lv_keyfigure TYPE rsiobjnm,
lv_length TYPE i,
lt_delta_value TYPE /cpd/t_pfp_delta_value,
ls_delta_value TYPE /cpd/s_pfp_delta_value,
* ls_key_figure LIKE LINE OF it_key_figure,
lr_plan TYPE REF TO /cpd/cl_pfp_ip_plan,
lv_eltuid TYPE rsz_uid,
lt_range TYPE rzd1_t_range,
ls_range TYPE rzd1_s_range,
lv_count TYPE c VALUE 1,
ls_plan_header TYPE /cpd/s_pfp_plan_header_d,
lv_mp_guid TYPE string.
DATA lv_field TYPE char10.
FIELD-SYMBOLS : <ft_data> TYPE ANY TABLE,
<fs_data> TYPE any,
<ls_def> TYPE rsr_s_variable_definition,
<fv_crid> TYPE any,
<fv_craid> TYPE any,
<fv_value> TYPE any,
<fv_uom> TYPE any,
<fv_currency> TYPE any,
<fv_resource> TYPE any,
<fv_resotype> TYPE any.
CONSTANTS : lc_query TYPE bsanly_query VALUE '/CPD/PFP_R01_IRQ0002',
lc_cpdcraid TYPE string VALUE 'C_CPDCRAID',
lc_cpdcrid TYPE string VALUE 'C_CPDCRID',
lc_cpdfuom TYPE string VALUE 'C_CPDFUOM',
lc_cpdfpcur TYPE string VALUE 'C_CPDFPCUR',
lc_quantity TYPE string VALUE 'QUAN',
lc_currency TYPE string VALUE 'CURR',
lc_resource TYPE string VALUE 'C_CPDFRES',
lc_resotype TYPE string VALUE 'C_CPDFRTYP'.
lv_mp_guid
= IV_MP_GUID.
SELECT issue_id activity_id plan_id FROM /iam/d_i_root AS i INNER JOIN /iam/d_act_root AS a ON a~par_issue_uuid = i~db_key
INTO TABLE lt_data WHERE ( i~stat_cd <> '04' OR i~stat_cd <> '05' ) AND a~act_category = 'CRA' AND i~db_key IN ( SELECT parent_key FROM /iam/d_i_obj_ref AS o
WHERE id = lv_mp_guid ).
READ TABLE lt_data INTO ls_data INDEX 1.
IF sy-subrc <> 0.
RETURN.
ENDIF.
lv_plan_header_id
= ls_data-plan_id.
*Soft switch Check: Do not procced if business function for PFP is not on
CHECK /cpd/cl_pfp_switch_check=>check_ca_cpd_sfws_pfp_1( ) = abap_true.
* Get Version ID
/cpd/cl_pfp_po_services=>get_ph_details(
EXPORTING
iv_plan_id = lv_plan_header_id " Plan ID
IMPORTING
es_plan_header = ls_plan_header " Table Type for Plan Header
).
/cpd/cl_pfp_po_customizing
=>get_active_version_type(
EXPORTING
iv_plan_scen_id = ls_plan_header-plan_scen_id " Plan Scenario ID
IMPORTING
ev_ver_type_id = lv_version_type
).
* IF sy-subrc = 0.
IF lv_version_type IS NOT INITIAL.
/cpd/cl_pfp_po_services
=>get_version_details(
EXPORTING
iv_plan_id = lv_plan_header_id " Plan ID
IMPORTING
et_version = lt_plan_version " Plan Version Id
).
READ TABLE lt_plan_version INTO ls_plan_version WITH KEY version_type = lv_version_type.
IF sy-subrc = 0.
lv_version_id = ls_plan_version-version_id.
CALL METHOD /cpd/cl_pfp_ip_plan=>get_instance
RECEIVING
re_instance = lr_plan.
CALL METHOD lr_plan->set_plan
EXPORTING
i_planoid = lv_plan_header_id.
* Resetting analytical Instance
cl_bs_anly_list_services=>reset(
IMPORTING
ev_subrc = lv_subrc " Return Value of ABAP Statements
et_message = lt_message " Analytics: Messages
).
* Instantiation
cl_bs_anly_list_services=>get_data_instance(
EXPORTING
iv_query = lc_query
IMPORTING
eo_data = lo_data
ev_subrc = lv_subrc
).
APPEND lc_query TO lt_query.
cl_bs_anly_list_services
=>get_selection_instance(
EXPORTING
it_query = lt_query
IMPORTING
eo_selection = lo_selection
ev_subrc = lv_subrc
).
* Get Variable Metadata
lo_selection->get_variables(
IMPORTING
et_def = lt_def ).
* Read current selection
lo_selection->read(
IMPORTING
et_selection = lt_selection
ev_subrc = lv_subrc
).
* Change selection
READ TABLE lt_def ASSIGNING <ls_def> WITH KEY iobjnm = /cpd/cl_pfp_constants=>gc_fpoid.
* Query must have a variable for project
CHECK sy-subrc EQ 0.
DELETE lt_selection WHERE fieldname = <ls_def>-vnam.
CLEAR ls_selection.
ls_selection-fieldname = <ls_def>-vnam.
ls_selection-sign = 'I'.
ls_selection-option = 'EQ'.
ls_selection-low = lv_plan_header_id.
INSERT ls_selection INTO TABLE lt_selection.
READ TABLE lt_def ASSIGNING <ls_def> WITH KEY iobjnm = /cpd/cl_pfp_constants=>gc_fver.
* Query must have a variable for plan header
CHECK sy-subrc EQ 0.
DELETE lt_selection WHERE fieldname = <ls_def>-vnam.
CLEAR ls_selection.
ls_selection-fieldname = <ls_def>-vnam.
ls_selection-sign = 'I'.
ls_selection-option = 'EQ'.
ls_selection-low = lv_version_id.
INSERT ls_selection INTO TABLE lt_selection.
READ TABLE lt_def ASSIGNING <ls_def> WITH KEY iobjnm = /cpd/cl_pfp_constants=>gc_crid.
* Query must have a variable for plan header
CHECK sy-subrc EQ 0.
DELETE lt_selection WHERE fieldname = <ls_def>-vnam.
CLEAR ls_selection.
LOOP AT lt_data INTO ls_data WHERE issue_id IS NOT INITIAL.
ls_selection-fieldname = <ls_def>-vnam.
ls_selection-sign = 'I'.
ls_selection-option = 'EQ'.
ls_selection-low = ls_data-issue_id.
INSERT ls_selection INTO TABLE lt_selection.
ENDLOOP.
READ TABLE lt_def ASSIGNING <ls_def> WITH KEY iobjnm = /cpd/cl_pfp_constants=>gc_craid.
* Query must have a variable for plan header
CHECK sy-subrc EQ 0.
DELETE lt_selection WHERE fieldname = <ls_def>-vnam.
CLEAR ls_selection.
LOOP AT lt_data INTO ls_data WHERE NOT alt_id IS INITIAL AND issue_id IS NOT INITIAL.
SHIFT ls_data-alt_id LEFT BY 4 PLACES.
ls_selection
-fieldname = <ls_def>-vnam.
ls_selection-sign = 'I'.
ls_selection-option = 'EQ'.
ls_selection-low = ls_data-alt_id.
INSERT ls_selection INTO TABLE lt_selection.
ENDLOOP.
* Writeback selection
lo_selection->write(
EXPORTING
it_selection = lt_selection ).
*Check selection
lo_selection->check(
IMPORTING
ev_subrc = lv_subrc
).
CHECK lv_subrc = 0.
* Read data
lo_data->read(
IMPORTING
et_columns = lt_columns
er_t_data = lr_t_data
ev_subrc = lv_subrc
et_message = lt_message
).
READ TABLE lt_columns INTO ls_columns WITH KEY col_type = 'K'.
lv_eltuid = ls_columns-iobjnm.
CALL FUNCTION 'RSZ_0_DB_ELT_GET'
EXPORTING
i_eltuid = lv_eltuid
IMPORTING
e_t_range = lt_range.
DATA: lv_cost TYPE /PICM/EST_COST.
* Fill all key value
ASSIGN lr_t_data->* TO <ft_data>.
LOOP AT <ft_data> ASSIGNING <fs_data>.
ASSIGN COMPONENT 'K0002_CPDFPCA' OF STRUCTURE <fs_data> TO <fv_value>.
IF sy-subrc = 0 AND <fv_value> IS ASSIGNED.
lv_cost = lv_cost + <fv_value>.
ENDIF.
ENDLOOP.
ENDIF.
ENDIF.
EV_DATA
= lv_cost.
**********************************************************************
**Code to change the input to query so it won't pick from buffer next time
* Change selection
READ TABLE lt_def ASSIGNING <ls_def> WITH KEY iobjnm = /cpd/cl_pfp_constants=>gc_fpoid.
* Query must have a variable for project
CHECK sy-subrc EQ 0.
DELETE lt_selection WHERE fieldname <> <ls_def>-vnam.
IF lo_selection IS BOUND.
* Writeback selection
lo_selection->write(
EXPORTING
it_selection = lt_selection ).
* Check selection
lo_selection->check(
IMPORTING
ev_subrc = lv_subrc
* et_message = lt_message
).
CHECK lv_subrc = 0.
ENDIF.
ENDMETHOD.