Update: Judging by a comment by the OP, it sounds like glenn jackman's recommendation to switch from letting ret_ID() set a global variable in order to return its result to outputting its result to stdout and capturing the result in a command substitution ($(...)) solved the problem.
Assuming that the problem wasn't the simple logic error Glenn points out (((ID+=ID)) should be ((ID+=req_ID )): The exact cause of the original problem is not known, but since both func() and ret_ID() operate on global variables, it's easy to see how one function could interfere with the other, such as if ret_ID() accidentally also sets variable $ID.
Here's a rewrite of the function that shows this change, and also suggests a few other changes to make the function more robust, most notably the use of local variables:
func()
{
# Declare *local* variables.
local arg enum sourceID retID
# Declare the local result variable *as an integer*
# Also, better to use variable names that at least start with a *lowercase*
# letter to avoid conflicts with *environment* variables.
local -i id=0
# ...
for arg; do # loop over all args; the `in "$@"` part is optional
enum="source"
sourceID=$arg
# Call helper function and let it return its result via *stdout* captured
# through a command substitution rather than by setting a global variable.
# Note the use of double quotes to prevent problems with values with embedded spaces.
reqID=$(ret_ID "$FILE_NAME" "$sourceID" "$enum")
# Add the value returned to $id
# Note that since $id was declared as an integer,
# use of (( ... )) is optional.
id+=$reqID
done
echo "$id"
}
$IDcan never be an odd value. You set it's value, then double it. You are not accumulating anything. You only return twice the last value of$req_ID. Did you mean((ID+=req_ID))?ret_IDshould return a value, not just set a global variable.