one of the documented procedures in this installation of the ACS
im_force_user_to_enter_project_report   conn   args   why
What it does:
If a user is not on vacation and is late with their project report, Send them to a screen to enter that project report. Sets state in session so user is only asked once per session.
Defined in: /web/philip/tcl/intranet-defs.tcl

Source code:

    if { ![im_enabled_p] } {
	# intranet or hours-logging not turned on. Do nothing
	return filter_ok
    set last_prompted_time [ad_get_client_property intranet user_asked_to_fill_out_project_reports_p]

    if { ![empty_string_p $last_prompted_time] &&  $last_prompted_time > [expr [ns_time] - 60*60*24] } {
	# We have already asked the user in this session, within the last 24 hours, 
	# to enter their missing project report
	return filter_ok

    set user_id [ad_get_user_id]
    if { $user_id == 0 } {
	# This can't happen on standard acs installs since intranet is protected
	# But we check any way to prevent bugs on other installations
	return filter_ok

    # Let's make a note that the user has been prompted 
    # to enter project reports. This saves us the database 
    # hit next time. 
    ad_set_client_property -persistent f intranet user_asked_to_fill_out_project_reports_p [ns_time]

    # build up a list of all the project reports we need to fill out
    # We'll use this as a stack to go through all project reports 
    #  until we're out of places to go
    set groups_list [list]
    set db [ns_db gethandle]

    # first check if the user is no vacation
    set user_on_vacation [database_to_tcl_string $db  "select nvl(u.on_vacation_until,sysdate-1) - sysdate from users u where u.user_id='$user_id'"]
    if { $user_on_vacation > 0 } {
	# we're on vacation right now. no need to log hours
	ns_db releasehandle $db
	return filter_ok

    set group_name_id_list [im_list_late_project_report_groups_for_user $db $user_id]

    ns_db releasehandle $db

    if { [llength $group_name_id_list] == 0 } {
	# no late project reports
	return filter_ok

    # We have late project reports - let's build up a fancy return_url
    # first the current url - the last place we want to go
    set return_url [im_url_with_query]
    foreach { group_name group_id } $group_name_id_list {
	set return_url "[im_url_stub]/projects/report-add?[export_url_vars group_id return_url]"
    ad_returnredirect $return_url
    return filter_return