Index: openacs-4/contrib/packages/project-manager/tcl/task-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/tcl/Attic/task-procs.tcl,v
diff -u -r1.18 -r1.19
--- openacs-4/contrib/packages/project-manager/tcl/task-procs.tcl 24 Jul 2004 08:33:54 -0000 1.18
+++ openacs-4/contrib/packages/project-manager/tcl/task-procs.tcl 13 Jan 2005 13:54:35 -0000 1.19
@@ -13,7 +13,24 @@
namespace eval pm::task {}
+ad_proc -public pm::task::name {
+ {-task_item_id:required}
+} {
+ Returns the name of the task
+
+ @author Jade Rubick (jader@bread.com)
+ @creation-date 2004-10-25
+
+ @param task_item_id
+ @return
+
+ @error -1
+} {
+ return [db_string get_name { } -default "-1"]
+}
+
+
ad_proc -public pm::task::options_list {
{-edit_p "f"}
-project_item_id
@@ -81,7 +98,7 @@
SELECT
r.item_id,
r.title as task_title
- FROM
+ FROM
pm_tasks_revisionsx r,
cr_items i,
pm_tasks_active t
@@ -147,6 +164,173 @@
}
+ad_proc -public pm::task::options_list_html {
+ {-edit_p "f"}
+ -project_item_id
+ {-task_item_id ""}
+ {-dependency_task_id ""}
+ {-dependency_task_ids ""}
+ {-number "0"}
+ {-depends_on_new ""}
+ {-current_number "0"}
+} {
+ Returns a list of options suiteable for HTML.
+ Contains a list of possible tasks that this task can
+ depend upon, or selected. These tasks are limited to just the
+ one project.
+
+
+
+ There is one special case that we handle: if you are creating new
+ tasks (not editing), you can have them depend on each other.
+ So if you create two tasks at the same time, you may want task
+ 2 to depend on task 1. Instead of a task_item_id, we then
+ specify a value of this form:
+
+
+ numX
+
+
+ where X represents the number of the new task, ranging from 1
+ to n.
+
+
+
+ To be more efficient when creating multiple tasks at the same
+ time, we should cache the database calls.
+
+ @author Jade Rubick (jader@bread.com)
+ @creation-date 2004-05-13
+
+ @param edit_p Is this for a task being edited? Or a new task?
+
+ @param project_item_id The project we're finding tasks from
+
+ @param task_item_id The task ID. This is used because we do not
+ want a task to depend on itself, so it is excluded from the list.
+
+ @param dependency_task_ids For edited tasks, the current task_ids
+ that it depends on. Used because sometimes it can be closed, and
+ it wouldn't otherwise appear on the list. This is a list.
+
+ @param dependency_task_id For edited tasks, the current task that
+ it depends on, used for setting the default option in HTML.
+
+ @param number When the list is returned, it includes entries for
+ number new tasks, in the numX format described in these docs.
+
+ @param depends_on_new When you're using a process, you want the
+ dependency to be on other new tasks. The format for this should
+ be num1 num2, etc.. So we make the default if this parameter is set.
+
+ @param current_number The current number. Used for new tasks. It
+ prevents allowing dependencies on the task being created.
+
+ @return
+
+ @error
+} {
+
+ # get tasks this task can depend on
+
+ if {[exists_and_not_null dependency_task_ids]} {
+
+ set union_clause "
+ UNION
+ SELECT
+ r.item_id,
+ r.title as task_title
+ FROM
+ pm_tasks_revisionsx r,
+ cr_items i,
+ pm_tasks_active t
+ WHERE
+ r.parent_id = :project_item_id and
+ r.revision_id = i.live_revision and
+ i.item_id = t.task_id
+ and t.task_id in ([join $dependency_task_ids ","])"
+ } else {
+ set union_clause ""
+ }
+
+ set keys [list]
+
+ db_foreach get_dependency_tasks { } {
+ set options($task_title) $item_id
+ lappend keys $task_title
+ }
+
+ set keys [lsort $keys]
+
+ # ---------------------------------------------------------------
+ # Start setting up the output.
+ # These are for new tasks, the already created tasks are added to
+ # the list later.
+ # ---------------------------------------------------------------
+
+ set dependency_options_full " "
+
+ if {[string is false $edit_p]} {
+
+ # now set up dependency options
+
+ for {set j 1} {$j <= $number} {incr j} {
+
+ if {[string equal $depends_on_new $j]} {
+ set selected "selected=\"selected\" "
+ } else {
+ set selected ""
+ }
+
+ if {![string equal $current_number $j]} {
+ append dependency_options_full " "
+ }
+ }
+ }
+
+ # -------------------------------------------------
+ # Now add the tasks that are already in the project
+ # -------------------------------------------------
+
+
+ if {[string is true $edit_p]} {
+ foreach key $keys {
+
+ # for editing tasks, we skip ourselves (because depending on
+ # ourselves just sometimes isn't an option)
+ if {![string equal $task_item_id $options($key)]} {
+
+ if {[string equal $options($key) $dependency_task_id]} {
+ set selected "selected=\"selected\" "
+ } else {
+ set selected ""
+ }
+
+ # check for case when there is a quote in the name of
+ # a task. We have to filter this out, or we get an
+ # error. -- not sure what this comment is for -- JR
+
+
+ append dependency_options_full " "
+ }
+ }
+ } else {
+
+ foreach key $keys {
+
+ # check for case when there is a quote in the name of a
+ # task. We have to filter this out, or we get an error. --
+ # not sure what this comment is for -- JR
+
+ append dependency_options_full " "
+ }
+ }
+
+
+ return $dependency_options_full
+}
+
+
ad_proc -public pm::task::dependency_delete_all {
-task_item_id:required
@@ -156,13 +340,14 @@
@author Jade Rubick (jader@bread.com)
@creation-date 2004-02-23
- @param task_item_id The task we wish to remove the dependencies from
+ @param task_item_id The task we wish to remove the dependencies from.
@return
@error
} {
- db_dml delete_deps "delete from pm_task_dependency where task_id = :task_item_id"
+ db_dml delete_deps { }
+
return 1
}
@@ -214,16 +399,7 @@
@error
} {
- set project_tasks [db_list get_tasks "
- SELECT
- task.item_id as t_item_id
- FROM
- cr_items task,
- cr_items project
- WHERE
- task.parent_id = project.item_id and
- project.item_id = :project_item_id
- "]
+ set project_tasks [db_list get_tasks { }]
# we do not allow tasks to depend on items outside of their
# project. So if it's not in the list of tasks for that project,
@@ -239,15 +415,7 @@
if {$loop_limit > 0} {
set dep_list [list]
- db_foreach get_dependencies "
- SElECT
- d.task_id as dep_task,
- d.parent_task_id as dep_task_parent
- FROM
- pm_task_dependency d
- WHERE
- d.task_id in ([join $project_tasks ", "])
- " {
+ db_foreach get_dependencies { } {
lappend dep_list d-$dep_task-$dep_task_parent
}
@@ -266,12 +434,11 @@
}
-
- if {[string equal $valid_p "TRUE"]} {
+ if {[string is true $valid_p]} {
# after it passes
set dependency_id [db_nextval pm_task_dependency_seq]
- db_dml insert_dep "insert into pm_task_dependency (dependency_id, task_id, parent_task_id, dependency_type) values (:dependency_id, :task_item_id, :parent_id, 'finish_before_start')"
+ db_dml insert_dep { }
} else {
ns_log Notice "Task dependency for $task_item_id on $parent_id was not added due to looping or being outside of the current project"
@@ -450,16 +617,17 @@
-title:required
-description:required
{-mime_type "text/plain"}
+ {-comment ""}
+ {-comment_type "text/plain"}
-end_date:required
-percent_complete:required
-estimated_hours_work:required
-estimated_hours_work_min:required
-estimated_hours_work_max:required
- -actual_hours_worked:required
- {-status_id}
-update_user:required
-update_ip:required
-package_id:required
+ {-priority "0"}
} {
@@ -474,6 +642,9 @@
@param description
+ @param comment The comment to send out by email if the task
+ is closed. Otherwise, it is NOT sent out.
+
@param mime_type
@param end_date
@@ -486,10 +657,6 @@
@param estimated_hours_work_max
- @param actual_hours_worked The number of hours worked to date
-
- @param status_id The code representing the status
-
@param update_user The user updating the task
@param update_ip The IP address of the request
@@ -500,50 +667,42 @@
@error
} {
- if {![exists_and_not_null status_id]} {
- set status_id [pm::task::current_status \
- -task_item_id $task_item_id]
- }
-
# simple sanity check for min and max estimated hours
if {$estimated_hours_work_min > $estimated_hours_work_max} {
set temp $estimated_hours_work_max
set estimated_hours_work_max $estimated_hours_work_min
set estimated_hours_work_min $temp
}
+ if {$percent_complete >= 100} {
+
+ set status_id [pm::task::default_status_closed]
+
+ } elseif {$percent_complete < 100} {
+
+ set status_id [pm::task::default_status_open]
+ }
+
+ set actual_hours_worked [pm::task::update_hours \
+ -task_item_id $task_item_id]
+
set return_val [db_exec_plsql new_task_revision { *SQL }]
# we have to update all logged hours to make sure the hours are
- # updated whenever the project is changed.
+ # set to the correct project whenever the project is changed.
set logger_project [pm::project::get_logger_project -project_item_id $project_item_id]
- db_dml update_logger_entries {
- UPDATE
- logger_entries
- SET
- project_id = :logger_project
- WHERE
- entry_id in
- (select logger_entry from pm_task_logger_proj_map where task_item_id = :task_item_id)
- }
+ db_dml update_logger_entries { }
- # if the we've done 100% of the work, then we close the task
- if {$percent_complete >= 100} {
- pm::task::close -task_item_id $task_item_id
- } else {
- pm::task::open -task_item_id $task_item_id
- }
-
return $return_val
}
ad_proc -public pm::task::new {
-project_id:required
- -title:required
+ {-title "Subject missing"}
{-description ""}
{-mime_type "text/plain"}
{-end_date ""}
@@ -553,10 +712,26 @@
{-estimated_hours_work_max "0"}
{-creation_date ""}
{-status_id ""}
+ {-process_instance_id ""}
-creation_user:required
-creation_ip:required
-package_id:required
+ {-priority "0"}
} {
+ Creates a new task.
+
+ @param process_instance_id If a process was used to create the
+ task, then it is linked in to that process instance, so we can
+ things like display only tasks that are a part of a process.
+
+ @author Jade Rubick (jader@bread.com)
+ @creation-date who knows?
+
+ @return new task_item_id
+
+ @error
+
+} {
if {![exists_and_not_null status_id]} {
set status_id [pm::task::default_status_open]
}
@@ -567,9 +742,15 @@
set estimated_hours_work_min $temp
}
- set return_val [db_exec_plsql new_task_item { *SQL }]
+ set task_revision [db_exec_plsql new_task_item { *SQL }]
+ set task_item_id [pm::task::get_item_id \
+ -task_id $task_revision]
- return $return_val
+ if {$percent_complete >= 100} {
+ pm::task::close -task_item_id $task_item_id
+ }
+
+ return $task_item_id
}
@@ -618,12 +799,12 @@
ad_proc -public pm::task::get_url {
object_id
} {
- # set package_id [db_string get_package_id {}]
- # set package_url [site_node::get_url_from_object_id -object_id $package_id]
- # set package_url [site_node::get_url_from_object_id -object_id $object_id]
- #return "${package_url}task-one?task_id=$object_id"
- return {}
- # "/project-manager/task-one?task_id=$object_id"
+ set url [pm::util::url]
+
+ set package_url "${url}task-one?task_id=$object_id"
+
+ return $package_url
+
}
@@ -728,16 +909,16 @@
select sum(le.value) from logger_entries le where entry_id in (select logger_entry from pm_task_logger_proj_map where task_item_id = :task_item_id) and le.variable_id = '[logger::variable::get_default_variable_id]'
" -default "0"]
- if {[string equal $update_tasks_p "t"]} {
+ if {[string is true $update_tasks_p]} {
- db_dml update_current_task "
+ db_dml update_current_task {
UPDATE
pm_tasks_revisions
SET
actual_hours_worked = :total_logged_hours
WHERE
task_revision_id = :task_revision_id
- "
+ }
}
return $total_logged_hours
@@ -799,11 +980,40 @@
@error
} {
- db_dml remove_assignment "
- delete from pm_task_assignment where task_id = :task_item_id"
+
+ db_dml remove_assignment { }
+
+ # Flush the cache that remembers which roles to offer the current user in the 'assign role to myself' listbox
+ util_memoize_flush [list pm::role::task_select_list_filter_not_cached -task_item_id $task_item_id -party_id [ad_conn user_id]]
}
+ad_proc -public pm::task::unassign {
+ -task_item_id:required
+ -party_id:required
+} {
+ Removes an assignment for a task
+
+ @author Jade Rubick (jader@bread.com)
+ @creation-date 2004-11-18
+
+ @param task_item_id
+
+ @param party_id
+
+ @return
+
+ @error
+} {
+ db_dml remove_assignment { }
+
+ # Flush the cache that remembers which roles to offer the current user in the 'assign role to myself' listbox
+ if {[ad_conn user_id] == $party_id} {
+ util_memoize_flush [list pm::role::task_select_list_filter_not_cached -task_item_id $task_item_id -party_id $party_id]
+ }
+}
+
+
ad_proc -public pm::task::assign {
-task_item_id:required
-party_id:required
@@ -820,172 +1030,88 @@
@param role_id the role under which the person is assigned
- @return
+ @return
@error
} {
if {![exists_and_not_null role_id]} {
set role_id [pm::role::default]
}
- db_dml add_assignment "
- insert into pm_task_assignment
- (task_id,
- role_id,
- party_id)
- values
- (:task_item_id,
- :role_id,
- :party_id)
- "
+ db_transaction {
+ # make sure we avoid case when that assignment has already
+ # been made.
+ db_dml delete_assignment {
+ delete from
+ pm_task_assignment
+ where
+ task_id = :task_item_id and
+ party_id = :party_id
+ }
+
+ db_dml add_assignment {
+ insert into pm_task_assignment
+ (task_id,
+ role_id,
+ party_id)
+ values
+ (:task_item_id,
+ :role_id,
+ :party_id)
+ }
+ }
+
+ # Flush the cache that remembers which roles to offer the current user in the 'assign role to myself' listbox
+ if {[ad_conn user_id] == $party_id} {
+ util_memoize_flush [list pm::role::task_select_list_filter_not_cached -task_item_id $task_item_id -party_id $party_id]
+ }
}
-ad_proc -public pm::task::open {
+ad_proc -public pm::task::assigned_p {
-task_item_id:required
+ -party_id:required
} {
- Opens a task, and sends notifications, unless it was already
- open. If it was already open, does nothing.
+ Returns 1 if assigned, 0 if not
@author Jade Rubick (jader@bread.com)
- @creation-date 2004-04-22
+ @creation-date 2004-11-18
@param task_item_id
+ @param party_id
+
@return
@error
} {
- # find out what the status of the task was, and while we're at it,
- # get other interesting information about the task, in case we
- # want to close it. Then we can put this info in the email.
+ return [db_string assigned_p { } -default 0]
+}
- db_1row get_status "
- SELECT
- t.status,
- s.status_type,
- s.description as status_description,
- r.title as task_title,
- r.estimated_hours_work,
- r.estimated_hours_work_min,
- r.estimated_hours_work_max,
- to_char(r.earliest_start, 'YYYY-MM-DD HH24:MI:SS') as earliest_start_ansi,
- to_char(r.earliest_finish, 'YYYY-MM-DD HH24:MI:SS') as earliest_finish_ansi,
- to_char(r.latest_start, 'YYYY-MM-DD HH24:MI:SS') as latest_start_ansi,
- to_char(r.latest_finish, 'YYYY-MM-DD HH24:MI:SS') as latest_finish_ansi,
- r.description as task_description,
- r.mime_type,
- project_revision.title as project_name
- FROM
- pm_tasks t,
- cr_items task_item,
- pm_task_status s,
- pm_tasks_revisionsx r,
- cr_items project_item,
- cr_revisions project_revision
- WHERE
- r.parent_id = project_item.item_id and
- t.task_id = task_item.item_id and
- task_item.live_revision = r.revision_id and
- project_item.live_revision = project_revision.revision_id and
- r.item_id = t.task_id and
- t.status = s.status_id and
- t.task_id = :task_item_id"
- if {[string equal $status_type "o"]} {
+ad_proc -public pm::task::open {
+ {-task_item_id:required}
+} {
+ Opens a task.
+
+ @author Jade Rubick (jader@bread.com)
+ @creation-date 2004-04-22
+
+ @param task_item_id
- # this is already open
- return
-
- }
-
- # set the new status
-
+ @return
+
+ @error
+} {
set status_code [pm::task::default_status_open]
- db_dml update_status "
- UPDATE
- pm_tasks
- SET
- status = :status_code
- WHERE
- task_id = :task_item_id"
-
- # send out an email notification
-
- set earliest_start [lc_time_fmt $earliest_start_ansi "%x"]
- set earliest_finish [lc_time_fmt $earliest_finish_ansi "%x"]
- set latest_start [lc_time_fmt $latest_start_ansi "%x"]
- set latest_finish [lc_time_fmt $latest_finish_ansi "%x"]
-
- set assignees [pm::task::assignee_email_list -task_item_id $task_item_id]
-
- if {[llength $assignees] > 0} {
-
- set to_address $assignees
-
- set user_id [ad_conn user_id]
-
- set from_address [db_string get_from_email "select email from parties where party_id = :user_id" -default "nobody@nowhere.com"]
-
- set task_url "[parameter::get_from_package_key -package_key acs-kernel -parameter SystemURL][ad_conn package_url]task-one?task_id=$task_item_id"
-
- set subject "Task reopened (was $status_description): $task_title"
-
- if {[string is true [parameter::get_from_package_key -package_key project-manager -parameter UseUncertainCompletionTimesP]]} {
- set estimated_work "\nHrs work (min): $estimated_hours_work_min\nHrs work (max): $estimated_hours_work_max"
- } else {
- set estimated_work "\nHrs work: $estimated_hours_work"
-
- }
-
- set notification_text "Task reopened, was $status_description\n\n"
-
- set task_description [ad_html_text_convert -from $mime_type -to "text/plain" -- $task_description]
-
- append notification_text "
--------------
-Task ID: \#$task_item_id
-Subject: $task_title
-Project: $project_name
-
-Link: $task_url
-
----------------
-Estimated work:
----------------$estimated_work
-
-------
-Dates:
-------
-Earliest start: $earliest_start
-Earliest finish: $earliest_finish
-Latest start: $latest_start
-Latest finish $latest_finish
-
------------
-Description
------------
-$task_description"
-
-
- append notification_text "\n"
-
- pm::util::email \
- -to_addr $to_address \
- -from_addr $from_address \
- -subject $subject \
- -body $notification_text
- }
-
- return
+ db_dml update_status { }
}
ad_proc -public pm::task::close {
- -task_item_id:required
+ {-task_item_id:required}
} {
- Closes a task, and sends notifications, unless it was already
- closed. If it was already closed, does nothing.
+ Closes a task
@author Jade Rubick (jader@bread.com)
@creation-date 2004-04-22
@@ -996,165 +1122,10 @@
@error
} {
- # find out what the status of the task was
-
- db_1row get_status "
- SELECT
- t.status,
- s.status_type,
- s.description as status_description,
- r.title as task_title,
- r.estimated_hours_work,
- r.estimated_hours_work_min,
- r.estimated_hours_work_max,
- to_char(r.earliest_start, 'YYYY-MM-DD HH24:MI:SS') as earliest_start_ansi,
- to_char(r.earliest_finish, 'YYYY-MM-DD HH24:MI:SS') as earliest_finish_ansi,
- to_char(r.latest_start, 'YYYY-MM-DD HH24:MI:SS') as latest_start_ansi,
- to_char(r.latest_finish, 'YYYY-MM-DD HH24:MI:SS') as latest_finish_ansi,
- r.description as task_description,
- r.mime_type,
- project_revision.title as project_name
- FROM
- pm_tasks t,
- cr_items task_item,
- pm_task_status s,
- pm_tasks_revisionsx r,
- cr_items project_item,
- cr_revisions project_revision
- WHERE
- r.parent_id = project_item.item_id and
- t.task_id = task_item.item_id and
- task_item.live_revision = r.revision_id and
- project_item.live_revision = project_revision.revision_id and
- r.item_id = t.task_id and
- t.status = s.status_id and
- t.task_id = :task_item_id"
-
- if {[string equal $status_type "c"]} {
-
- # this is already closed
- return
-
- }
-
- # set the new status
-
set status_code [pm::task::default_status_closed]
- db_dml update_status "
- UPDATE
- pm_tasks
- SET
- status = :status_code
- WHERE
- task_id = :task_item_id"
+ db_dml update_status { }
- # send out an email notification
-
- set earliest_start [lc_time_fmt $earliest_start_ansi "%x"]
- set earliest_finish [lc_time_fmt $earliest_finish_ansi "%x"]
- set latest_start [lc_time_fmt $latest_start_ansi "%x"]
- set latest_finish [lc_time_fmt $latest_finish_ansi "%x"]
-
-
- set assignees [pm::task::assignee_email_list -task_item_id $task_item_id]
-
- if {[llength $assignees] > 0} {
-
- set to_address $assignees
-
- set user_id [ad_conn user_id]
-
- set from_address [db_string get_from_email "select email from parties where party_id = :user_id" -default "nobody@nowhere.com"]
-
- set last_time_stamp ""
- set work_log "----------------------\nWork done on this task\n----------------------\n\n"
-
- db_foreach get_logged_time "
- SELECT
- to_char(le.time_stamp, 'fmDyfm fmMMfm-fmDDfm-YYYY') as time_stamp_pretty,
- le.value,
- le.description,
- r.title as task_name,
- submitter.first_names || ' ' || submitter.last_name as user_name
- FROM
- logger_entries le,
- cr_items i,
- cr_revisions r,
- pm_task_logger_proj_map m,
- logger_projects lp,
- acs_objects ao,
- acs_users_all submitter
- WHERE
- r.item_id = m.task_item_id and
- i.live_revision = r.revision_id and
- r.item_id = :task_item_id and
- le.project_id = lp.project_id and
- ao.object_id = le.entry_id and
- le.entry_id = m.logger_entry and
- ao.creation_user = submitter.user_id
- ORDER BY
- le.time_stamp desc" {
- if {![string equal $time_stamp_pretty $last_time_stamp]} {
- append work_log "* $time_stamp_pretty\n\n"
- }
- append work_log "[pm::util::string_truncate_and_pad -length 15 -string "$user_name:"] $description ($value hrs)\n"
-
- set last_time_stamp $time_stamp_pretty
- }
-
- set task_url "[parameter::get_from_package_key -package_key acs-kernel -parameter SystemURL][ad_conn package_url]task-one?task_id=$task_item_id"
-
- set subject "Task closed (was $status_description) $task_title"
-
- if {[string is true [parameter::get_from_package_key -package_key project-manager -parameter UseUncertainCompletionTimesP]]} {
- set estimated_work "\nHrs work (min): $estimated_hours_work_min\nHrs work (max): $estimated_hours_work_max"
- } else {
- set estimated_work "\nHrs work: $estimated_hours_work"
-
- }
-
- set notification_text "Task closed, was $status_description\n\n"
-
- set task_description [ad_html_text_convert -from $mime_type -to "text/plain" -- $task_description]
-
- append notification_text "
--------------
-Task ID: \#$task_item_id
-Description: $task_title
-Project: $project_name
-
-Link: $task_url
-"
- append notification_text "\n\n$work_log"
-
- append notification_text "
----------------
-Estimated work:
----------------$estimated_work
-
-------
-Dates:
-------
-Earliest start: $earliest_start
-Earliest finish: $earliest_finish
-Latest start: $latest_start
-Latest finish $latest_finish
-
------------
-Description
------------
-$task_description"
-
-
- pm::util::email \
- -to_addr $to_address \
- -from_addr $from_address \
- -subject $subject \
- -body $notification_text
- }
-
- return
}
@@ -1163,7 +1134,7 @@
set send_email_p [parameter::get_from_package_key -package_key "project-manager" -parameter SendDailyEmail -default "0"]
- if {[string equal $send_email_p "0"]} {
+ if {[string is false $send_email_p]} {
ns_log Notice "Parameter SendDailyEmail for project manager says skip email today"
return
}
@@ -1180,7 +1151,7 @@
# what if the person assigned is no longer a part of the subsite?
# right now, we still email them.
- db_foreach get_all_open_tasks "
+ db_foreach get_all_open_tasks {
SELECT
ts.task_id,
ts.task_id as item_id,
@@ -1221,46 +1192,45 @@
t.item_id = ta.task_id and
ta.party_id = p.party_id
ORDER BY
- t.latest_start asc" {
- set earliest_start_pretty [lc_time_fmt $earliest_start "%x"]
- set earliest_finish_pretty [lc_time_fmt $earliest_finish "%x"]
- set latest_start_pretty [lc_time_fmt $latest_start "%x"]
- set latest_finish_pretty [lc_time_fmt $latest_finish "%x"]
+ t.latest_start asc
+ } {
+ set earliest_start_pretty [lc_time_fmt $earliest_start "%x"]
+ set earliest_finish_pretty [lc_time_fmt $earliest_finish "%x"]
+ set latest_start_pretty [lc_time_fmt $latest_start "%x"]
+ set latest_finish_pretty [lc_time_fmt $latest_finish "%x"]
+
+ if {[exists_and_not_null earliest_start_j]} {
+ set slack_time [pm::task::slack_time \
+ -earliest_start_j $earliest_start_j \
+ -today_j $today_j \
+ -latest_start_j $latest_start_j]
- if {[exists_and_not_null earliest_start_j]} {
- set slack_time [pm::task::slack_time \
- -earliest_start_j $earliest_start_j \
- -today_j $today_j \
- -latest_start_j $latest_start_j]
-
- }
-
- if {[lsearch $parties $party_id] == -1} {
- lappend parties $party_id
- }
-
- lappend task_list($party_id) $task_id
- set titles_arr($task_id) $title
- set ls_arr($task_id) $latest_start_pretty
- set lf_arr($task_id) $latest_finish_pretty
- set slack_arr($task_id) $slack_time
-
- # how many tasks does this person have?
- if {[info exists task_count($party_id)]} {
- incr task_count($party_id)
- } else {
- set task_count($party_id) 1
- }
}
+
+ if {[lsearch $parties $party_id] == -1} {
+ lappend parties $party_id
+ }
+
+ lappend task_list($party_id) $task_id
+ set titles_arr($task_id) $title
+ set ls_arr($task_id) $latest_start_pretty
+ set lf_arr($task_id) $latest_finish_pretty
+ set slack_arr($task_id) $slack_time
+ set roles($task_id-$party_id) $role
+
+ # how many tasks does this person have?
+ if {[info exists task_count($party_id)]} {
+ incr task_count($party_id)
+ } else {
+ set task_count($party_id) 1
+ }
+ }
# transitions are < this value
set OVERDUE_THRESHOLD 0
set PRESSING_THRESHOLD 7
set LONGTERM_THRESHOLD 90
- set TASK_LENGTH 70
- set TASK_ID_LENGTH 9
-
foreach party $parties {
set subject "Daily Task status report"
@@ -1272,6 +1242,8 @@
foreach task $task_list($party) {
+ set url [pm::task::get_url $task]
+
if {$slack_arr($task) < $OVERDUE_THRESHOLD} {
set which_pile overdue
} elseif {$slack_arr($task) < $PRESSING_THRESHOLD} {
@@ -1284,87 +1256,110 @@
if {![empty_string_p $which_pile]} {
- set trimmed_task [pm::util::string_truncate_and_pad -length $TASK_ID_LENGTH -string $task]
- set trimmed_title [pm::util::string_truncate_and_pad -length $TASK_LENGTH -string $titles_arr($task)]
+ lappend $which_pile "
+
"
- set overdue_title "OVERDUE TASKS"
- set overdue_title [pm::util::string_truncate_and_pad -length $TASK_LENGTH -string $overdue_title]
-
set overdue_description "consult with people affected, and let them know deadlines are affected"
- set pressing_title "PRESSING TASKS"
- set pressing_title [pm::util::string_truncate_and_pad -length $TASK_LENGTH -string $pressing_title]
+ set pressing_title "
Pressing Tasks
"
set pressing_description "you need to start working on these soon to avoid affecting deadlines"
- set longterm_title "LONG TERM TASKS"
- set longterm_title [pm::util::string_truncate_and_pad -length $TASK_LENGTH -string $longterm_title]
+ set longterm_title "
Long Term Tasks
"
+
set longterm_description "look over these to plan ahead"
# okay, let's now set up the email body
- lappend description "This is a daily reminder of tasks that are assigned to you"
- lappend description "You current have $task_count($party) tasks assigned to you"
+ set description "
+
This is a daily reminder of tasks that are assigned to you
+You currently have $task_count($party) tasks assigned to you
"
+
+ pm::util::email \
-to_addr $address \
-from_addr $address \
-subject $subject \
- -body [join $description "\n"]
-
+ -body $description \
+ -mime_type "text/html"
}
- # consider also sending out emails to people who have assigned
- # tickets to nobody
+ # consider also sending out emails to people who have created
+ # tickets that are not assigned to anyone
}
@@ -1389,25 +1384,10 @@
ad_proc -public pm::task::email_alert {
-task_item_id:required
- {-user_id ""}
- {-assignee_id ""}
- {-assignee_role_name ""}
{-edit_p "t"}
{-comment ""}
- {-description ""}
- {-description_mime_type "text/plain"}
- {-old_description ""}
- {-old_description_mime_type "text/plain"}
- {-subject ""}
- {-work ""}
- {-work_min ""}
- {-work_max ""}
- {-project_name ""}
- {-earliest_start ""}
- {-earliest_finish ""}
- {-latest_start ""}
- {-latest_finish ""}
- {-url ""}
+ {-comment_mime_type "text/plain"}
+ {-extra_description ""}
} {
Sends out an email notification when changes have been made to a task
@@ -1422,193 +1402,147 @@
@param task_item_id
- @param user_id The user making the change
-
- @param assignee_id The party_id of the user assigned to the task.
-
- @param assignee_role_name The role name for what the party is
- assigned to do
-
@param edit_p Is this an edited task, or a new one? t for edited,
f otherwise.
+
+ @param extra_description Additional email content to send. In text format.
- @param description
-
- @param old_description
-
- @param subject The one line description of the task
-
- @param work Estimated hours work
-
- @param work_min Estimated minimimum hours work
-
- @param work_max Estimated maximum hours work
-
- @param project_name
-
- @param earliest_start
-
- @param earliest_finish
-
- @param latest_start
-
- @param latest_finish
-
- @param url Optionally, a URL that the user is directed to
-
@return
@error
} {
- set task_term [parameter::get -parameter "Taskname" -default "Task"]
- set task_term_lower [parameter::get -parameter "taskname" -default "task"]
- set use_uncertain_completion_times_p [parameter::get -parameter "UseUncertainCompletionTimesP" -default "0"]
+ set task_term \
+ [parameter::get -parameter "Taskname" -default "Task"]
+ set task_term_lower \
+ [parameter::get -parameter "taskname" -default "task"]
+ set use_uncertain_completion_times_p \
+ [parameter::get -parameter "UseUncertainCompletionTimesP" -default "0"]
- # from address
+ set user_id [ad_conn user_id]
- if {![exists_and_not_null $user_id]} {
- set user_id [ad_conn user_id]
- }
+ db_1row get_from_address_and_more { }
- db_1row get_from_address_and_more {
- SELECT
- p.email as from_address,
- p2.first_names || ' ' || p2.last_name as mod_username
- FROM
- parties p,
- persons p2
- WHERE
- p.party_id = :user_id and
- p.party_id = p2.person_id
- }
+ db_1row get_task_info { }
- # to address
+ if {[string is true $edit_p]} {
- if {![exists_and_not_null assignee_id]} {
+ # ----
+ # EDIT
+ # ----
- # bug: we should get the list of assignees here.
- ns_log Error "the proc pm::task::email_alert is not complete: assignee"
-
- }
+ set subject_out "Edited $task_term \#$task_item_id: $subject"
+ set intro_text "$mod_username edited this $task_term_lower"
- set to_address [db_string get_email "select email from parties where party_id = :assignee_id"]
+ } else {
- # if they left out any of the task info, then we get it from the database
- if { \
- ![exists_and_not_null subject] || \
- ![exists_and_not_null work] || \
- ![exists_and_not_null work_min] || \
- ![exists_and_not_null work_max] || \
- ![exists_and_not_null project_name] || \
- ![exists_and_not_null earliest_start] || \
- ![exists_and_not_null earliest_finish] || \
- ![exists_and_not_null latest_start] || \
- ![exists_and_not_null latest_finish] \
- } {
-
- db_1row get_task_info {
- SELECT
- t.title as subject,
- to_char(t.earliest_start,'MM-DD-YYYY') as earliest_start,
- to_char(t.earliest_finish,'MM-DD-YYYY') as earliest_finish,
- to_char(t.latest_start,'MM-DD-YYYY') as latest_start,
- to_char(t.latest_finish,'MM-DD-YYYY') as latest_finish,
- t.estimated_hours_work as work,
- t.estimated_hours_work_min as work_min,
- t.estimated_hours_work_max as work_max,
- t.percent_complete,
- p.title as project_name
- FROM
- pm_tasks_revisionsx t,
- cr_items i,
- cr_items project,
- pm_projectsx p
- WHERE
- t.item_id = :task_item_id and
- t.revision_id = i.live_revision and
- t.item_id = i.item_id and
- t.parent_id = project.item_id and
- project.item_id = p.item_id and
- project.live_revision = p.revision_id
- }
+ # ---
+ # NEW
+ # ---
- }
-
-
- if {[string is true $edit_p]} {
- set subject_out "Edited $task_term \#$task_item_id: $subject"
- set intro_text "$mod_username edited this $task_term_lower"
- } else {
set subject_out "New $task_term \#$task_item_id: $subject"
set intro_text "$mod_username assigned you to a new $task_term_lower"
+
}
+
if {[empty_string_p $comment]} {
set comment_text ""
} else {
- set comment_text "--------\nCOMMENT:\n--------\n$comment\n\n"
+ set comment_text "
Comment:
$comment"
}
+
+ set url [pm::task::get_url $task_item_id]
- if {[exists_and_not_null url]} {
- set task_url $url
- } else {
- set task_url "unavailable"
- }
+ set description [ad_html_text_convert -from $description_mime_type -to "text/html" -- $description]
+ set extra_description [ad_html_text_convert -from "text/plain" -to "text/html" -- $extra_description]
- set description [ad_html_text_convert -from $description_mime_type -to "text/plain" -- $description]
- set old_description [ad_html_text_convert -from $old_description_mime_type -to "text/plain" -- $old_description]
+ set description_out "$description $extra_description"
- if {![string equal $description $old_description] && [string is true $edit_p]} {
- set description_out "$description \n\n-------\nOld description:\n-------\n\n$old_description"
+ set assignees [db_list_of_lists get_assignees { }]
- append intro_text "\nSee below to see the changes in the description"
+ if {[exists_and_not_null $process_instance]} {
- } else {
- set description_out $description
- }
+ set process_url [pm::process::url \
+ -process_instance_id $process_instance \
+ -project_item_id $project_item_id]
- if {[string equal $use_uncertain_completion_times_p 1]} {
- set estimated_work "\nHrs work (min): $work_min"
- append estimated_work "\nHrs work (max): $work_max"
+ set process_description [pm::process::name \
+ -process_instance_id $process_instance]
+
+ set process_html "
+