So, here we go again with the second try. Instead of trying to tell everything at once Ill just concentrate on one topic. And for this week this is Value Determinations.
What is a value determination?
A value determination is an action that is triggered on the appraisal document by a cell. A cell is one specific column within one appraisal element. There are 2 types of value determinations:
1. Extracting value determinations
Here the value determination read data from somewhere outside of the document and places the result back into the appraisal document. This outside can be inside the R/3 system but also from other systems.
A delivered standard example is the implementation Strategic Objectives (technical name: HRHAP00_VAL_DET_005). This implementation reads based on the managers organization assignment the strategic enterprise goals for his department out of the SEM system and places these goals as a note in the appraisal document.
2. Calculating value determinations
This type takes the available document data to perform an action on it. Mostly this is a calculation. The result is normally placed on the cell that triggered the value determination.
A good example would be the Average value determination HRHAP00_VAL_DET_001. The average calculation takes all the child elements for the calling element, calculates the average and writes this back to the element.
See also picture below. Here the calling element (Qualifications) gets the average value for all the child elements.
Both types of value determinations are achieved by one BAdI definition, HRHAP00_VAL_DET. Let us have a closer look at this definition. It consists out of the following methods:
This is the documentation method. In here a SE61 general text is assigned which contains the information about the specific implementation. When customizing the appraisal template you will see a blue I button which will give you the documentation. This method is always available in our BAdI definitions that can be enabled in the catalog.
In this method can be used to restrict already on customizing level on which columns the value determination can be set.
Is used to determine whether or not the implementation is visible for selection during customizing.
Can be used to control when a value determination is triggered. If a calculation should only be performed in the status In Process then this would be defined in here.
Should the value determination trigger dialog interaction then the implementation is UI dependent.
This method performs the actual action, calculation or external read and returns the result to one or more cells and/or cell notes.
Words are always nice, examples even better. One of the requests that comes up often is a value determination that does not give a vertical average (like in the above example) but a horizontal one. This to calculate for each element the average part appraisal score.
So what we want to achieve is that after both part appraisers are filled out their average score is put in the final appraisal column and this for each element.
To start we create a new implementation based on BAdI definition HRHAP00_VAL_DET. Assign a title and a unique filter value.
We leave in this example the methods GET_INFORMATION, CHECK_UI_DEPENDENCY and CHECK_EXECUTABILITY empty and start with implementing the customizing methods.
Our calculation uses the part appraiser column (column id PAPP) as source of the calculation. There for it should not be possible to assign this calculation to the part appraiser column itself.
Also, the calculation makes only sense if the template includes a part appraiser process. Checking if the column PAPP is available is the quickest way to make sure of it.
Both methods are triggered during configuration of the appraisal template. The calculation itself is triggered on the appraisal document via method VALUE_DETERMINATION. As this is the most important method of this definition lets have a look at the most interesting import, export, and changing parameters.
S_BASE_CELL contains the information which cell triggered the implementation. A cell is the combination of the element which can be identified by the ROW_IID and a column within this element (COLUMN_IID). All the elements are available in T_BODY_ELEMENTS and all the columns in T_BODY_COLUMNS. The actual values can then be found in T_BODY_CELLS and T_BODY_CELL_NOTES. These two tables are used for returning the calculated values and as such are changing.
So in our implementation we need to get the COLUMN_IIDs for the part appraiser values for the given element. Then add all the given part appraisal ratings and divide this by the number of part appraisers.
Just to make sure we check if the calculated value is a valid value for the value type. When this is the case we write the calculated value back to the base cell.
In coding this looks like:
*– Workarea definition DATA: lw_body_column TYPE hap_s_body_columns, lw_body_cell TYPE hap_s_body_cells.
*– Data definition DATA: l_total_num_val TYPE hap_value_num, l_nr_p_apper TYPE i, l_tabix TYPE sytabix, l_no_value_det TYPE char1.
*– Business-AddIn Definition DATA: l_exit_instance TYPE REF TO if_ex_hrhap00_value_type, l_exit_implemented TYPE char1.
*– Get the values for each part appraiser LOOP AT t_body_columns INTO lw_body_column WHERE column_id = ‘PAPP’. ” Part Appraisal Column READ TABLE t_body_cells WITH KEY row_iid = s_base_cell-row_iid column_iid = lw_body_column-column_iid INTO lw_body_cell. IF sy-subrc EQ 0. l_total_num_val = l_total_num_val + lw_body_cell-value_num. l_nr_p_apper = l_nr_p_apper + 1. ENDIF. CLEAR: lw_body_cell, lw_body_column. ENDLOOP.
IF l_nr_p_apper NE 0. *– Part Appraisal Values found -> Calc. Average l_total_num_val = l_total_num_val DIV l_nr_p_apper. *– Check validity of the calc and/or try to find the next valid value! READ TABLE t_body_cells INTO lw_body_cell WITH KEY row_iid = s_base_cell-row_iid column_iid = s_base_cell-column_iid BINARY SEARCH. IF sy-subrc = 0. “base element found *– Hold tabix of the base cell l_tabix = sy-tabix. * check whether the new calculated value is a valid one *VALID means: is it in the list of the value type * if not -> try to find the next valid value * Business Add-In: get implementation information and instance CALL FUNCTION ‘HRHAP_C_GET_BUSINESS_ADD_IN’ EXPORTING exit_name = c_badi_value_type flt_val = lw_body_cell-cell_value_class IMPORTING is_implemented = l_exit_implemented * tables * active_imps = CHANGING instance = l_exit_instance. IF NOT l_exit_implemented IS INITIAL. CALL METHOD l_exit_instance->get_next_valid_value EXPORTING flt_val = lw_body_cell-cell_value_class value_type = lw_body_cell-cell_value_type value = l_total_num_val no_value = l_no_value_det IMPORTING new_value = lw_body_cell-value_num new_no_value = lw_body_cell-no_value new_value_text = lw_body_cell-value_text EXCEPTIONS value_type_not_found = 1 OTHERS = 2. IF sy-subrc EQ 0. MODIFY t_body_cells FROM lw_body_cell INDEX l_tabix TRANSPORTING value_num value_text no_value. * new calculated appraisal entry (for BASE_CELL) new_value_determined = ‘X’. ENDIF. ENDIF. “base cell found? ENDIF. ENDIF.
Activate the implementation and register it for performance management via transaction OOHAP_BASIC. When this is done the implementation is available in the template catalog (transaction PHAP_CATALOG_PA) and ready for use.
Some comments: The implementation is just a prove of concept, for simplicity reasons I have left out several checks. The implementation assumes the values are coming from a numeric value type. It also assumes the final appraisal column and the part appraisal column use the same value type.