Batch control totals provide a mechanism for customizing the validation of batch contents to meet particular user requirements. This validation may be done for example, by doing total, or average operations on the batch lines and matching the values with values entered by the user.
Batches can be entered and viewed using the Batch Header window, and other windows available from it.
A control total type is predefined for checking the number of lines in a batch (control type = Total Lines).
You can create control totals to sum numerical element input values by defining a lookup for the lookup type CONTROL_TYPE. See: Setting Up BEE Validation Using Control Totals, Oracle HRMS Configuring, Reporting, and System Administration Guide
If you need other kinds of control totals, you can define lookups for them, but you must also write a validation procedure for checking the batch against the total. The next section explains how to write this validation procedure.
The following procedure is delivered with a null statement in it. Replace the null statement with your customized control total validation code.
Procedure: check_control
Package: user_check
File: pyusrchk.pkb
The check_control procedure is executed during the batch validation phase of the BEE process. The parameters passed to this procedure are:
p_batch_id The batch ID.
p_control_type The name of the control total.
p_control_total The user entered value to match.
Two other parameters (p_status, p_message) are used in this procedure to return an error code and message to the system if the batch control total validation fails.
Each line of batch data is stored as a record in the pay_batch_lines table. The data is stored in the fields value_1 - value_15. The number of the field corresponds to the column in the Batch Lines window.
For example, if you want to validate a check digit, you could use the following PL/SQL code as a basis:
PROCEDURE check_control
(
p_batch_id IN NUMBER,
p_control_type IN VARCHAR2,
p_control_total IN VARCHAR2,
p_status IN OUT VARCHAR2,
p_message OUT VARCHAR2
) IS
total NUMBER;
BEGIN
-- Check the control type is the one we're expecting
IF p_control_type = 'CHECK_DIGIT' THEN
-- Calculate the MOD 10 of total values in value_1
SELECT MOD(NVL(SUM(value_1),0),10) INTO total FROM pay_batch_lines
WHERE batch_id = p_batch_id;
-- Compare with the user entered value
IF total <> p_control_total THEN
-- Create the error message to return and set the status to E(rror)
p_message := 'Control total TOT1 (' || p_control_total ||
'does not match calculated value (' || total ||
')';
p_status := 'E';
ENDIF;
ENDIF;
END check_control;
This, however, is a very simplistic example. If batch lines within the same batch are entered for more than one element then the value columns may vary between elements. Here is a more complex example to validate the check digit on the input value 'Identification':
PROCEDURE check_control
(
p_batch_id IN NUMBER,
p_control_type IN VARCHAR2,
p_control_total IN VARCHAR2,
p_status IN OUT VARCHAR2,
p_message OUT VARCHAR2
) IS
CURSOR c1 IS
SELECT DISTINCT element_type_id
FROM pay_batch_lines
WHERE batch_id = p_batch_id;
--
r1 c1%ROWTYPE;
total NUMBER;
value_num NUMBER;
sqlstr VARCHAR2(200);
c2 INTEGER;
ret INTEGER;
BEGIN
--
-- Check the control type is the one we're expecting
IF p_control_type = 'CHECK_DIGIT2' THEN
total := 0;
--
-- Loop through each element in the batch lines
FOR r1 IN c1 LOOP
--
-- Find out the value number that 'Identification' is in
SELECT display_sequence
INTO value_num
FROM pay_input_values iv,
pay_batch_headers bh,
pay_element_types et
WHERE bh.batch_id = p_batch_id AND
iv.business_group_id = bh.business_group_id AND
et.element_type_id = r1.element_type_id AND
iv.element_type_id = et.element_type_id AND
iv.name = 'Identification';
--
-- Create an SQL string to add the values
sqlstr := 'SELECT MOD(NVL(SUM(value_' || value_num ||
'),0),10) ' ||
'FROM pay_batch_lines ' ||
'WHERE batch_id = ' || p_batch_id || ' AND '
||'element_type_id = ''' ||
r1.element_type_id || '''';
--
-- Call the string using dynamic SQL and put the value in 'total'
c2 := dbms_sql.open_cursor;
dbms_sql.parse (c2,sqlstr,dbms_sql.v7);
dbms_sql.define_column (c2,1,total);
ret := dbms_sql.execute (c2);
ret := dbms_sql.fetch_rows (c2);
--
-- Check we got some values back
if ret > 0 then
dbms_sql.column_value (c2,1,total);
else
total := 0;
end if;
--
dbms_sql.close_cursor (c2);
--
-- Check the total matches the user entered value and create an
-- error message if it doesn't
IF total <> p_control_total THEN
p_message := 'Check digit expected '||p_control_total||
' but got '||to_char(total);
p_status := 'E';
END IF;
END LOOP;
END IF;
END check_control;