Index: openacs-4/contrib/packages/project-manager/tcl/project-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/tcl/Attic/project-procs.tcl,v diff -u -r1.3 -r1.4 --- openacs-4/contrib/packages/project-manager/tcl/project-procs.tcl 4 Sep 2003 23:18:23 -0000 1.3 +++ openacs-4/contrib/packages/project-manager/tcl/project-procs.tcl 26 Jan 2004 15:39:40 -0000 1.4 @@ -12,7 +12,190 @@ namespace eval project_manager::project {} +ad_proc -public project_manager::project::latest_start { + end_date_j + hours_to_complete + hours_day +} { + # set latest_start($my_iid) [expr $task_deadline_j - [expr $activity_time($my_iid) / double($hours_day)]] + + # we now set the latest start. This is equal to the + # latest finish date minus the amount of time it will + # take to accomplish the job. We need to disregard holidays! + + set t_end_date $end_date_j + set t_today $t_end_date + + while {![is_workday_p $t_today]} { + set t_today [expr $t_today - 1] + } + set t_total_hours $hours_to_complete + + while {$t_total_hours > $hours_day} { + + set t_today [expr $t_today - 1] + + # if it is a holiday, don't subtract from total time + + if {[is_workday_p $t_today]} { + set t_total_hours [expr $t_total_hours - $hours_day] + } + + } + + return $t_today + +} + + +ad_proc -public project_manager::project::earliest_finish { + earliest_start_j + hours_to_complete + hours_day +} { + + # set earliest_finish($task_item) [expr $earliest_start($task_item) + [expr $activity_time($task_item) / double($hours_day)]] + + # we now set the earliest finish. This is equal to the + # earliest start plus the amount of time it will + # take to accomplish the job. We need to disregard holidays! + + set t_start_date $earliest_start_j + set t_today $t_start_date + + while {![is_workday_p $t_today]} { + set t_today [expr $t_today + 1] + } + set t_total_hours $hours_to_complete + + while {$t_total_hours > $hours_day} { + + set t_today [expr $t_today + 1] + + # if it is a holiday, don't subtract from total time + + if {[is_workday_p $t_today]} { + set t_total_hours [expr $t_total_hours - $hours_day] + } + + } + + return $t_today + +} + + +ad_proc -public project_manager::project::my_earliest_start { + earliest_start_j + hours_to_complete + hours_day +} { + Computing the earliest start requires getting a max of all the possible + candidates. This returns the value for one candidate +} { + # set my_earliest_start [expr [expr $activity_time($dependent_item) / double($hours_day)] + $earliest_start($dependent_item)] + + set t_start_date $earliest_start_j + set t_today $t_start_date + + while {![is_workday_p $t_today]} { + set t_today [expr $t_today + 1] + } + + set t_total_hours $hours_to_complete + + while {$t_total_hours > $hours_day} { + + set t_today [expr $t_today + 1] + + # if it is a holiday, don't subtract from total time + + if {[is_workday_p $t_today]} { + set t_total_hours [expr $t_total_hours - $hours_day] + } + + } + + return $t_today + +} + + +ad_proc -public project_manager::project::my_latest_finish { + latest_start_j + hours_to_complete + hours_day +} { + Computing the latest +} { + # set temp [expr $min_latest_start + [expr $activity_time($task_item) / double($hours_day)]] + + set t_start_date $latest_start_j + set t_today $t_start_date + + while {![is_workday_p $t_today]} { + set t_today [expr $t_today + 1] + } + + set t_total_hours $hours_to_complete + + while {$t_total_hours > $hours_day} { + + set t_today [expr $t_today + 1] + + # if it is a holiday, don't subtract from total time + + if {[is_workday_p $t_today]} { + set t_total_hours [expr $t_total_hours - $hours_day] + } + + } + + return $t_today + +} + + +ad_proc -public project_manager::project::julian_to_day_of_week { + julian_date +} { + Computes the day of the week. 0=Sunday + Initially, I used Tcl's clock command, but it doesn't accept dates + larger than 2038, so I had to do this myself. +} { + set date [dt_julian_to_ansi $julian_date] + regexp {([0-9]*)-([0-9]*)-([0-9]*)} $date match year month day + regexp {0(.)} $month match month extra + regexp {0(.)} $day match day extra + set alpha [expr [expr 14 - $month] / 12] + set y [expr $year - $alpha] + set m [expr $month + [expr 12 * $alpha] - 2] + set day_of_week_pre_mod [expr $day + $y + [expr $y / 4] - [expr $y / 100] + [expr $y / 400] + [expr 31 * $m / 12]] + set day_of_week [expr $day_of_week_pre_mod % 7] + return $day_of_week +} + +ad_proc -public project_manager::project::is_workday_p { + date_j +} { + + Figures out whether or not a given date is a workday or not + +} { + + # need to add in a table of holidays + + set day_of_week [julian_to_day_of_week $date_j] + + if {[string equal $day_of_week 6] || [string equal $day_of_week 0]} { + return 0 + } else { + return 1 + } +} + + ad_proc -public project_manager::project::compute_status {project_item_id} { Looks at tasks and subprojects, and computes the current status of a project. @@ -67,7 +250,7 @@ # -------------------------------------------------------------------- # for now, hardcode in a day is 8 hours. Later, we want to set this by - # person. Note also that it assumes everyone works 7 days a week + # person. # -------------------------------------------------------------------- set hours_day 8 @@ -97,6 +280,8 @@ set task_list [concat $task_list $task_list_project] + ns_log Notice "task_list: $task_list" + # ------------------------- # no tasks for this project # ------------------------- @@ -112,6 +297,7 @@ # today_j (julian date for today) db_1row tasks_group_query { } + ns_log notice "Julian today: $today_j" # -------------------------------------------------------------- # Set up activity_time for all tasks @@ -124,9 +310,12 @@ if {[exists_and_not_null task_deadline_j]} { + ns_log notice "$my_iid has a deadline $task_jdeadline_j" + set latest_finish($my_iid) $task_deadline_j - set latest_start($my_iid) [expr $task_deadline_j - [expr $activity_time($my_iid) / double($hours_day)]] + set latest_start($my_iid) [latest_start $task_deadline_j $activity_time($my_iid) $hours_day] + } } @@ -145,7 +334,7 @@ set dependency_types($task_item_id-$parent_task_id) $dependency_type - ns_log Notice "id: $dependency_id task: $task_item_id parent: $parent_task_id type: $dependency_type" + ns_log Notice "dependency (id: $dependency_id) task: $task_item_id parent: $parent_task_id type: $dependency_type" } @@ -190,7 +379,8 @@ if {![info exists depends($task_item)]} { set earliest_start($task_item) $start_date_j - set earliest_finish($task_item) [expr $earliest_start($task_item) + [expr $activity_time($task_item) / double($hours_day)]] + #set earliest_finish($task_item) [expr $earliest_start($task_item) + [expr $activity_time($task_item) / double($hours_day)]] + set earliest_finish($task_item) [earliest_finish $earliest_start($task_item) $activity_time($task_item) $hours_day] lappend present_tasks $task_item @@ -228,7 +418,7 @@ if {![exists_and_not_null earliest_start($task_item)]} { - ns_log Notice " info exists for $task_item" + ns_log Notice " !info exists for $task_item" # --------------------------------------------- # set the earliest_start for this task = @@ -237,19 +427,20 @@ # (i-1 means an item that this task depends on) # --------------------------------------------- - set max_earliest_start $today_j + set max_earliest_start 0 foreach dependent_item $depends($task_item) { - set my_earliest_start [expr [expr $activity_time($dependent_item) / double($hours_day)] + $earliest_start($dependent_item)] + set my_earliest_start [my_earliest_start $earliest_start($dependent_item) $activity_time($dependent_item) $hours_day] if {$my_earliest_start > $max_earliest_start} { set max_earliest_start $my_earliest_start } } set earliest_start($task_item) $max_earliest_start - set earliest_finish($task_item) [expr $max_earliest_start + [expr $activity_time($task_item) / double($hours_day)]] + # set earliest_finish($task_item) [expr $max_earliest_start + [expr $activity_time($task_item) / double($hours_day)]] + set earliest_finish($task_item) [earliest_finish $max_earliest_start $activity_time($task_item) $hours_day] ns_log Notice \ " earliest_start ($task_item): $earliest_start($task_item)" @@ -327,10 +518,14 @@ # info for these items # ----------------------------------------------------- + ns_log Notice "Starting foreach task-item $task_list" + foreach task_item $task_list { if {![info exists dependent($task_item)]} { + ns_log Notice " !info exists dependent($task_item)" + # we check this because some tasks already have # hard deadlines set. if {[info exists latest_finish($task_item)]} { @@ -339,7 +534,8 @@ set latest_finish($task_item) $end_date_j } - set late_start_temp [expr $latest_finish($task_item) - [expr $activity_time($task_item) / double($hours_day)]] + #set late_start_temp [expr $latest_finish($task_item) - [expr $activity_time($task_item) / double($hours_day)]] + set late_start_temp [latest_start $latest_finish($task_item) $activity_time($task_item) $hours_day] if {$late_start_temp < $latest_start($task_item)} { set latest_start($task_item) $late_start_temp @@ -348,12 +544,15 @@ } else { set latest_finish($task_item) $end_date_j - set latest_start($task_item) [expr $latest_finish($task_item) - [expr $activity_time($task_item) / double($hours_day)]] + #set latest_start($task_item) [expr $latest_finish($task_item) - [expr $activity_time($task_item) / double($hours_day)]] + set latest_start($task_item) [latest_start $latest_finish($task_item) $activity_time($task_item) $hours_day] } lappend present_tasks $task_item ns_log Notice "Begin latest_start($task_item): $latest_start($task_item) latest_finish: $latest_finish($task_item)" + } else { + ns_log Notice " info exists dependent($task_item)" } } @@ -381,7 +580,7 @@ ns_log Notice "this task_item: $task_item" # ----------------------------------------------------- - # some tasks may already have latest_start filled in + # some tasks may already have latest_start filled in. # the first run of tasks, for example, had their values # filled in earlier # ----------------------------------------------------- @@ -405,11 +604,15 @@ if {![exists_and_not_null latest_start($dependent_item)]} { # let's not do this task_item yet lappend future_tasks $task_item + ns_log Notice " defer" set defer_p t } else { - set my_latest_start [expr $latest_start($dependent_item) - [expr $activity_time($dependent_item) / double($hours_day)]] + #set my_latest_start [expr $latest_start($dependent_item) - [expr $activity_time($dependent_item) / double($hours_day)]] + set my_latest_start [latest_start $latest_start($dependent_item) $activity_time($task_item) $hours_day] + ns_log Notice " my_latest_start: $my_latest_start" + if {$my_latest_start < $min_latest_start} { set min_latest_start $my_latest_start } @@ -430,8 +633,12 @@ set latest_start($task_item) $min_latest_start } - set temp [expr $min_latest_start + [expr $activity_time($task_item) / double($hours_day)]] + ns_log Notice " min_latest_start: $min_latest_start" + # temp is temporary latest_finish + #set temp [expr $min_latest_start + [expr $activity_time($task_item) / double($hours_day)]] + set temp [my_latest_finish $min_latest_start $activity_time($task_item) $hours_day] + if {[exists_and_not_null latest_finish($task_item)]} { if {$temp < $latest_finish($task_item)} { set latest_finish($task_item) @@ -517,8 +724,8 @@ set root_folder [db_exec_plsql get_root_folder { }] - while {$parent_id != $root_folder} { - set parent_id [db_string get_parent_id {}] + while {$parent_id != $root_folder && $parent_id != "-1"} { + set parent_id [db_string get_parent_id {} -default "-1"] set last_item_id $my_item_id set my_item_id $parent_id }