Index: openacs-4/contrib/packages/project-manager/project-manager.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/Attic/project-manager.info,v diff -u -r1.12.2.6 -r1.12.2.7 --- openacs-4/contrib/packages/project-manager/project-manager.info 9 Feb 2004 16:27:00 -0000 1.12.2.6 +++ openacs-4/contrib/packages/project-manager/project-manager.info 27 Feb 2004 22:46:12 -0000 1.12.2.7 @@ -8,25 +8,26 @@ f project-manager - + Jade Rubick Project management tool for OpenACS - 2004-02-04 + 2004-02-27 Track tasks, estimates and actual progress for a project. See the <a href="http://openacs.org/projects/dotwrk/project_management/">project page</a> for more information. - + + - + Index: openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-custom-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/sql/postgresql/Attic/project-manager-custom-create.sql,v diff -u -r1.1.2.3 -r1.1.2.4 --- openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-custom-create.sql 5 Feb 2004 23:57:49 -0000 1.1.2.3 +++ openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-custom-create.sql 27 Feb 2004 22:46:12 -0000 1.1.2.4 @@ -24,6 +24,7 @@ -- the custom columns are added in. I put this here as a reminder -- that other columns can be added in as well. These custom items -- are in the custom-create.sql script + select content_type__create_attribute( 'pm_project', 'customer_id', Index: openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/sql/postgresql/Attic/project-manager-drop.sql,v diff -u -r1.10.2.6 -r1.10.2.7 --- openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-drop.sql 5 Feb 2004 23:57:49 -0000 1.10.2.6 +++ openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-drop.sql 27 Feb 2004 22:46:12 -0000 1.10.2.7 @@ -13,54 +13,6 @@ \i project-manager-custom-drop.sql \i project-manager-notifications-drop.sql --- task dependency types -drop table pm_task_dependency_types cascade; -drop table pm_task_dependency cascade; -drop sequence pm_task_dependency_seq; -drop sequence pm_tasks_number_seq; - -select content_type__drop_attribute ('pm_task', 'end_date', 't'); -select content_type__drop_attribute ('pm_task', 'percent_complete', 't'); -select content_type__drop_attribute ('pm_task', 'estimated_hours_work', 't'); -select content_type__drop_attribute ('pm_task', 'estimated_hours_work_min', 't'); -select content_type__drop_attribute ('pm_task', 'estimated_hours_work_max', 't'); -select content_type__drop_attribute ('pm_task', 'actual_hours_worked', 't'); -select content_type__drop_attribute ('pm_task', 'earliest_start', 't'); -select content_type__drop_attribute ('pm_task', 'earliest_finish', 't'); -select content_type__drop_attribute ('pm_task', 'latest_start', 't'); -select content_type__drop_attribute ('pm_task', 'latest_finish', 't'); - -------------- --- WORKGROUPS -------------- - -drop sequence pm_workgroup_seq; -drop table pm_workgroup_parties; -drop table pm_workgroup; - ------------- --- PROCESSES ------------- - -drop sequence pm_process_seq; -drop sequence pm_process_task_seq; -drop sequence pm_process_task_dependency_seq; - -drop table pm_process_task_assignment; -drop table pm_process_task_dependency; -drop table pm_process_task; -drop table pm_process; - ---------- --- OTHERS ---------- -drop table pm_default_roles; -drop table pm_project_assignment; -drop table pm_task_assignment; -drop table pm_roles; -drop sequence pm_role_seq; - - create function inline_0 () returns integer as ' declare @@ -84,16 +36,6 @@ select inline_0(); drop function inline_0(); -select drop_package('pm_task'); - - ------------ --- PROJECTS ------------ - ---drop permissions -delete from acs_permissions where object_id in (select project_id from pm_projects); - -- unregister content_types from folder create function inline_0 () returns integer as ' @@ -110,53 +52,21 @@ from cr_items where - content_type = ''pm_project'' + content_type = ''pm_task'' LOOP - PERFORM pm_project__delete_project_item(v_item_cursor.item_id); + PERFORM pm_project__delete_task_item(v_item_cursor.item_id); END LOOP; - select content_item__get_id(''projects'', null, ''f'') into v_folder_id from dual; + -- this table must not hold reference to ''pm_tasks'' type + delete from cr_folder_type_map where content_type = ''pm_tasks''; - -- unregister_content_types - PERFORM content_folder__unregister_content_type ( - v_folder_id, -- folder_id - ''pm_project'', -- content_type - ''t'' -- include_subtypes - ); - - -- this table must not hold reference to ''pm_project'' type - delete from cr_folder_type_map where content_type = ''pm_project''; - - -- delete projects folder - PERFORM content_folder__delete(v_folder_id); - - -- delete the content folders - FOR v_item_cursor IN - select f.folder_id - from cr_folders f, - cr_items i - where f.folder_id = i.item_id and - description = ''Project Repository'' - LOOP - PERFORM content_item__delete(v_item_cursor.folder_id); - END LOOP; - return 0; end; ' language 'plpgsql'; select inline_0(); drop function inline_0(); --- drop package, which drops all functions created with define_function_args -select drop_package('pm_project'); - ---drop table -drop table pm_projects cascade; - -drop sequence pm_project_status_seq; -drop table pm_project_status; - -- unregister content_types from folder create function inline_0 () returns integer as ' @@ -173,26 +83,41 @@ from cr_items where - content_type = ''pm_task'' + content_type = ''pm_project'' LOOP - PERFORM pm_project__delete_task_item(v_item_cursor.item_id); + PERFORM pm_project__delete_project_item(v_item_cursor.item_id); END LOOP; - --select content_item__get_id(''tasks'', null, ''f'') into v_folder_id from dual; + return 0; +end; +' language 'plpgsql'; - -- unregister_content_types - --PERFORM content_folder__unregister_content_type ( - -- v_folder_id, -- folder_id - -- ''pm_tasks'', -- content_type - -- ''t'' -- include_subtypes - --); +select inline_0(); +drop function inline_0(); - -- this table must not hold reference to ''pm_project'' type - delete from cr_folder_type_map where content_type = ''pm_tasks''; +-- unregister content_types from folder +create function inline_0 () +returns integer as ' +declare + v_folder_id cr_folders.folder_id%TYPE; + v_item_id cr_items.item_id%TYPE; + v_item_cursor RECORD; +begin - -- delete projects folder - --PERFORM content_folder__delete(v_folder_id); + FOR v_item_cursor IN + select folder_id from cr_folders where description=''Project Repository'' + LOOP + PERFORM content_folder__unregister_content_type ( + v_item_cursor.folder_id, -- folder_id + ''pm_project'', -- content_type + ''t'' -- include_subtypes + ); + PERFORM content_folder__delete(v_item_cursor.folder_id); + END LOOP; + -- this table must not hold reference to ''pm_project'' type + delete from cr_folder_type_map where content_type = ''pm_project''; + return 0; end; ' language 'plpgsql'; @@ -201,8 +126,78 @@ drop function inline_0(); +-- task dependency types +drop table pm_task_dependency_types cascade; +drop table pm_task_dependency cascade; +drop sequence pm_task_dependency_seq; +drop sequence pm_tasks_number_seq; + +select content_type__drop_attribute ('pm_task', 'end_date', 't'); +select content_type__drop_attribute ('pm_task', 'percent_complete', 't'); +select content_type__drop_attribute ('pm_task', 'estimated_hours_work', 't'); +select content_type__drop_attribute ('pm_task', 'estimated_hours_work_min', 't'); +select content_type__drop_attribute ('pm_task', 'estimated_hours_work_max', 't'); +select content_type__drop_attribute ('pm_task', 'actual_hours_worked', 't'); +select content_type__drop_attribute ('pm_task', 'earliest_start', 't'); +select content_type__drop_attribute ('pm_task', 'earliest_finish', 't'); +select content_type__drop_attribute ('pm_task', 'latest_start', 't'); +select content_type__drop_attribute ('pm_task', 'latest_finish', 't'); + +------------- +-- WORKGROUPS +------------- + +drop sequence pm_workgroup_seq; +drop table pm_workgroup_parties; +drop table pm_workgroup; + +------------ +-- PROCESSES +------------ + +drop sequence pm_process_seq; +drop sequence pm_process_task_seq; +drop sequence pm_process_task_dependency_seq; + +drop table pm_process_task_assignment; +drop table pm_process_task_dependency; +drop table pm_process_task; +drop table pm_process; + +--------- +-- OTHERS +--------- +drop table pm_default_roles; +drop table pm_project_assignment; +drop table pm_task_assignment; +drop table pm_roles; +drop sequence pm_role_seq; + + +select drop_package('pm_task'); + + +----------- +-- PROJECTS +----------- + +--drop permissions +delete from acs_permissions where object_id in (select project_id from pm_projects); + + +-- drop package, which drops all functions created with define_function_args +select drop_package('pm_project'); + +--drop table +drop table pm_projects cascade; + +drop sequence pm_project_status_seq; +drop table pm_project_status cascade; + + + drop sequence pm_task_status_seq; -drop table pm_task_status; +drop table pm_task_status cascade; drop table pm_tasks cascade; drop table pm_tasks_revisions cascade; Index: openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-functions-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/sql/postgresql/Attic/project-manager-functions-create.sql,v diff -u -r1.8.2.7 -r1.8.2.8 --- openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-functions-create.sql 9 Feb 2004 16:27:22 -0000 1.8.2.7 +++ openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-functions-create.sql 27 Feb 2004 22:46:12 -0000 1.8.2.8 @@ -280,7 +280,7 @@ select define_function_args('pm_project__new_project_revision', 'item_id, project_name, project_code, parent_id, goal, description, planned_start_date, planned_end_date, actual_start_date, actual_end_date, ongoing_p, status_id, organization_id, creation_date, creation_user, creation_ip, package_id'); -create or replace function pm_project__new_project_revision ( +create function pm_project__new_project_revision ( integer, -- item_id varchar, -- project_name varchar, -- project_code @@ -313,7 +313,7 @@ p_actual_end_date alias for $10; p_ongoing_p alias for $11; p_status_id alias for $12; - p_organization_id alias for $13; + p_customer_id alias for $13; p_creation_date alias for $14; p_creation_user alias for $15; p_creation_ip alias for $16; @@ -349,10 +349,8 @@ v_revision_id, p_project_code, p_goal, p_planned_start_date, p_planned_end_date, p_actual_start_date, - p_actual_end_date, p_ongoing_p, p_status_id, p_organization_id); + p_actual_end_date, p_ongoing_p, p_status_id, p_customer_id); - -- make sure organizations are in as well - PERFORM acs_permission__grant_permission( v_revision_id, p_creation_user, @@ -406,9 +404,9 @@ returns varchar as ' declare p_pm_task_id alias for $1; - v_pm_task_name pm_tasks.title%TYPE; + v_pm_task_name cr_items.name%TYPE; begin - select i.name || ''_'' || p_pm_task_id into v_pm_project_name + select i.name || ''_'' || p_pm_task_id into v_pm_task_name from cr_items i where i.item_id = p_pm_task_id; return v_pm_task_name; @@ -553,7 +551,7 @@ p_actual_hours_worked alias for $10; p_status_id alias for $11; p_creation_date alias for $12; - p_creation_user alias for $13 + p_creation_user alias for $13; p_creation_ip alias for $14; p_package_id alias for $15; Index: openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-notifications-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/sql/postgresql/Attic/project-manager-notifications-create.sql,v diff -u -r1.1.2.1 -r1.1.2.2 --- openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-notifications-create.sql 10 Jan 2004 01:04:02 -0000 1.1.2.1 +++ openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-notifications-create.sql 27 Feb 2004 22:46:12 -0000 1.1.2.2 @@ -14,15 +14,15 @@ ''NotificationType'', ''pm_task_notif_type'', ''GetURL'', - ''project_manager::task::get_url'', + ''pm::task::get_url'', ''TCL'' ); v_foo := acs_sc_impl_alias__new ( ''NotificationType'', ''pm_task_notif_type'', ''ProcessReply'', - ''project_manager::task::process_reply'', + ''pm::task::process_reply'', ''TCL'' ); Index: openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-table-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/sql/postgresql/Attic/project-manager-table-create.sql,v diff -u -r1.15.2.7 -r1.15.2.8 --- openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-table-create.sql 6 Feb 2004 18:37:47 -0000 1.15.2.7 +++ openacs-4/contrib/packages/project-manager/sql/postgresql/project-manager-table-create.sql 27 Feb 2004 22:46:12 -0000 1.15.2.8 @@ -52,6 +52,7 @@ not null constraint pm_projects_status_id_fk references pm_project_status, + -- if ongoing_p is true, then actual_end_date must be null ongoing_p char(1) default 'f' constraint pm_projects_ongoing_p_ck check (ongoing_p in ('t','f')), Index: openacs-4/contrib/packages/project-manager/tcl/install-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/tcl/Attic/install-procs.tcl,v diff -u -r1.2.2.2 -r1.2.2.3 --- openacs-4/contrib/packages/project-manager/tcl/install-procs.tcl 5 Feb 2004 23:57:49 -0000 1.2.2.2 +++ openacs-4/contrib/packages/project-manager/tcl/install-procs.tcl 27 Feb 2004 22:46:13 -0000 1.2.2.3 @@ -11,10 +11,10 @@ } -namespace eval project_manager::install {} +namespace eval pm::install {} -ad_proc -private project_manager::install::package_instantiate { +ad_proc -private pm::install::package_instantiate { {-package_id:required} } { Package instantiation callback proc. @@ -24,15 +24,15 @@ # db_exec_plsql create_project { } } -ad_proc -private project_manager::install::package_uninstantiate { +ad_proc -private pm::install::package_uninstantiate { {-package_id:required} } { Package un-instantiation callback proc } { # Delete the project repository - # ns_log Debug "project_manager::install::package_uninstantiate getting folder_id for package_id: $package_id" + # ns_log Debug "pm::install::package_uninstantiate getting folder_id for package_id: $package_id" # set folder_id [db_exec_plsql get_folder_id { }] - # ns_log Debug "project_manager::install::package_uninstantiate delete folder_id: $folder_id" + # ns_log Debug "pm::install::package_uninstantiate delete folder_id: $folder_id" # db_exec_plsql delete_root_folder { } } Index: openacs-4/contrib/packages/project-manager/tcl/project-manager-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/tcl/Attic/project-manager-procs.tcl,v diff -u -r1.1.2.2 -r1.1.2.3 --- openacs-4/contrib/packages/project-manager/tcl/project-manager-procs.tcl 5 Feb 2004 23:57:49 -0000 1.1.2.2 +++ openacs-4/contrib/packages/project-manager/tcl/project-manager-procs.tcl 27 Feb 2004 22:46:13 -0000 1.1.2.3 @@ -10,10 +10,10 @@ } -namespace eval project_manager::project::util {} +namespace eval pm::project::util {} -ad_proc -public project_manager::project::util::datenvl { +ad_proc -public pm::project::util::datenvl { -value -value_if_null -value_if_not_null Index: openacs-4/contrib/packages/project-manager/tcl/project-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/tcl/Attic/project-procs-postgresql.xql,v diff -u -r1.2.2.2 -r1.2.2.3 --- openacs-4/contrib/packages/project-manager/tcl/project-procs-postgresql.xql 5 Feb 2004 23:57:49 -0000 1.2.2.2 +++ openacs-4/contrib/packages/project-manager/tcl/project-procs-postgresql.xql 27 Feb 2004 22:46:13 -0000 1.2.2.3 @@ -3,16 +3,40 @@ postgresql7.3 - + + SELECT + live_revision + FROM + cr_items + WHERE + item_id = :project_item_id + + + + + + SELECT + i.item_id + FROM + cr_items i, + cr_revisions r + WHERE + i.item_id = r.item_id and + r.revision_id = :project_id + + + + + select status_id from pm_project_status where status_type = 'o' limit 1 - + select status_id from pm_project_status @@ -21,7 +45,7 @@ - + select pm_project__new_project_item ( :project_name, @@ -44,7 +68,7 @@ - + select item_id, @@ -55,7 +79,7 @@ - + select sum(t.actual_hours_worked) as actual_hours_completed, @@ -69,7 +93,7 @@ - + select t.actual_hours_worked as worked, @@ -84,7 +108,7 @@ - + select d.dependency_id, @@ -98,33 +122,34 @@ - + select to_char(planned_start_date,'J') as start_date_j, - to_char(planned_end_date,'J') as end_date_j + to_char(planned_end_date,'J') as end_date_j, + ongoing_p from pm_projects where project_id = (select live_revision from cr_items where item_id = :project_item_id) - + update pm_projects set actual_hours_completed = :actual_hours_completed, estimated_hours_total = :estimated_hours_total, - earliest_finish_date = 'J[expr floor([set max_earliest_finish])]', - latest_finish_date = 'J[expr ceil([set min_latest_start])]' + earliest_finish_date = :max_earliest_finish, + latest_finish_date = :min_latest_start where project_id = (select live_revision from cr_items where item_id = :project_item_id) - + select parent_id @@ -135,21 +160,21 @@ - + select pm_project__get_root_folder (:package_id, 'f') - + update pm_tasks_revisions set - earliest_start = 'J[expr ceil( [set earliest_start($task_item)])]', - earliest_finish = 'J[expr ceil( [set earliest_finish($task_item)])]', - latest_start = 'J[expr floor([set latest_start($task_item)])]', - latest_finish = 'J[expr floor([set latest_finish($task_item)])]' + earliest_start = :es, + earliest_finish = :ef, + latest_start = :ls, + latest_finish = :lf where task_revision_id = (select live_revision from cr_items where item_id = :task_item) 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.2.3 -r1.3.2.4 --- openacs-4/contrib/packages/project-manager/tcl/project-procs.tcl 5 Feb 2004 23:57:49 -0000 1.3.2.3 +++ openacs-4/contrib/packages/project-manager/tcl/project-procs.tcl 27 Feb 2004 22:46:13 -0000 1.3.2.4 @@ -10,27 +10,67 @@ } -namespace eval project_manager::project {} +namespace eval pm::project {} -ad_proc -public project_manager::project::default_status_open { +ad_proc -public pm::project::get_project_id { + -project_item_id:required } { + Returns the live project_id when give the project_item_id + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-02-19 + + @param project_item_id The item_id for the project + + @return project_id + + @error +} { + set return_val [db_string get_project_id { }] + + return $return_val +} + + + +ad_proc -public pm::project::get_project_item_id { + -project_id:required +} { + Returns the item_id for a project when given the project_id + (a revision id) + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-02-19 + + @param project_id + + @return project_item_id + + @error +} { + set return_val [db_string get_project_item { }] + + return $return_val +} + + +ad_proc -public pm::project::default_status_open {} { Returns the default status value for open projects } { set return_val [db_string get_default_status_open { }] return $return_val } -ad_proc -public project_manager::project::default_status_closed { -} { +ad_proc -public pm::project::default_status_closed {} { Returns the default status value for closed projects } { set return_val [db_string get_default_status_closed { }] return $return_val } -ad_proc -public project_manager::project::new { +ad_proc -public pm::project::new { -project_name:required {-project_code ""} {-parent_id ""} @@ -48,24 +88,58 @@ -creation_ip:required -package_id:required } { + Creates a new project + @author Jade Rubick (jader@bread.com) + + @param project_name + + @error +} { + + # if the project is ongoing, there is no end date + # we set it to null to signify that. Technically, this + # is bad data model design -- we should just get rid of + # ongoing_p + if {[string equal $ongoing_p t]} { + set actual_end_date "" + set planned_end_date "" + } + set return_val [db_exec_plsql new_project_item { *SQL }] return $return_val } -ad_proc -public project_manager::project::latest_start { - end_date_j - hours_to_complete - hours_day + +ad_proc -public pm::project::latest_start { + {-end_date_j:required} + {-hours_to_complete:required} + {-hours_day:required} } { + Returns the latest_start date. This is equal to the + latest finish date minus the amount of time it will + take to accomplish the job. Also takes into + account weekdays. +

+ Someday, it should disregard holidays! + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-02-20 + + @param end_date_j - # set latest_start($my_iid) [expr $task_deadline_j - [expr $activity_time($my_iid) / double($hours_day)]] + @param hours_to_complete Estimated number of hours it will take + to complete this task - # 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! + @param hours_day Number of hours in a day + @return the latest start date, as a Julian number + + @error +} { + + set t_end_date $end_date_j set t_today $t_end_date @@ -91,7 +165,7 @@ } -ad_proc -public project_manager::project::earliest_finish { +ad_proc -public pm::project::earliest_finish { earliest_start_j hours_to_complete hours_day @@ -128,7 +202,7 @@ } -ad_proc -public project_manager::project::my_earliest_start { +ad_proc -public pm::project::my_earliest_start { earliest_start_j hours_to_complete hours_day @@ -164,7 +238,7 @@ } -ad_proc -public project_manager::project::my_latest_finish { +ad_proc -public pm::project::my_latest_finish { latest_start_j hours_to_complete hours_day @@ -199,7 +273,7 @@ } -ad_proc -public project_manager::project::julian_to_day_of_week { +ad_proc -public pm::project::julian_to_day_of_week { julian_date } { Computes the day of the week. 0=Sunday @@ -218,11 +292,12 @@ return $day_of_week } -ad_proc -public project_manager::project::is_workday_p { +ad_proc -public pm::project::is_workday_p { date_j } { - Figures out whether or not a given date is a workday or not + Figures out whether or not a given date is a workday or not. + Assumes Saturday and Sunday are not workdays } { @@ -238,11 +313,12 @@ } -ad_proc -public project_manager::project::compute_status {project_item_id} { +ad_proc -public pm::project::compute_status {project_item_id} { Looks at tasks and subprojects, and computes the current status of a project. - +

These are the items we'd like to compute - + +

     PROJECTS:
     estimated_completion_date       timestamptz,
     earliest_completion_date        timestamptz,
@@ -254,22 +330,42 @@
     earliest_finish(i) = earliest_start(i) + activity_time(i)
     latest_start(i)    = min(last_start(i+1) - activity_time(i)
     latest_finish(i)   = latest_start(i) + activity_time(i)
+    
- The statistics are computed based on: + Tasks in ongoing projects are given null completion dates. + The statistics are computed based on: +

project statistics are based on that project + subproject statistics +

+ that means if a project has a subproject, then the tasks for + both of those projects are put together in one list, and computed + together. +

- that means if a project has a subproject, then the tasks for both of those projects are put together in one list, and computed together. - so for a project with no subprojects, the values are computed for the tasks in that project +

for a project with subprojects, the statistics are based on the tasks of both of those projects. - this function returns a list of task_item_ids of all tasks under +

+ this function returns a project, plus all subproject tasks. + @author Jade Rubick (jader@bread.com) + @creation-date 2004-02-19 + + @param project_item_id The item_id for the project + + @return a list of task_item_ids of all tasks under a project, plus all subproject tasks. This is done so that the function can be recursive + + @error No error codes + } { + # Before hacking on this, you might want to look at: + # http://www.joelonsoftware.com/articles/fog0000000069.html + # TODO: # # ------------------------------------------------------------------------- @@ -288,7 +384,7 @@ # should look at: # http://mscmga.ms.ic.ac.uk/jeb/or/netaon.html - ns_log Notice "-----------------------------------------" + # ns_log Notice "-----------------------------------------" # -------------------------------------------------------------------- # for now, hardcode in a day is 8 hours. Later, we want to set this by @@ -312,7 +408,7 @@ # --------------------------------------------- # gets all tasks that are a part of subprojects # --------------------------------------------- - set project_return [project_manager::project::compute_status $my_id] + set project_return [pm::project::compute_status $my_id] set task_list_project [concat $task_list_project $project_return] } elseif {[string equal $my_type "pm_task"]} { @@ -322,7 +418,7 @@ set task_list [concat $task_list $task_list_project] - ns_log Notice "task_list: $task_list" + # ns_log Notice "task_list: $task_list" # ------------------------- # no tasks for this project @@ -339,7 +435,7 @@ # today_j (julian date for today) db_1row tasks_group_query { } - ns_log notice "Julian today: $today_j" + # ns_log notice "Julian today: $today_j" # -------------------------------------------------------------- # Set up activity_time for all tasks @@ -352,7 +448,7 @@ if {[exists_and_not_null task_deadline_j]} { - ns_log notice "$my_iid has a deadline $task_jdeadline_j" + # ns_log notice "$my_iid has a deadline $task_jdeadline_j" set latest_finish($my_iid) $task_deadline_j @@ -376,7 +472,7 @@ set dependency_types($task_item_id-$parent_task_id) $dependency_type - ns_log Notice "dependency (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" } @@ -385,9 +481,16 @@ # task information off of them # -------------------------------------------------------------- - # gives up planned_start_date and planned_end_date + # gives up end_date_j, start_date_j, and ongoing_p + # if ongoing_p is t, then end_date_j should be null db_1row project_info { } + if {[string equal $ongoing_p t] && ![empty_string_p end_date_j]} { + ns_log Error "Project cannot be ongoing and have a non-null end-date" + set end_date_j "" + } + + # -------------------------------------------------------------- # task_list contains all the tasks # a subset of those do not depend on any other tasks @@ -426,19 +529,19 @@ lappend present_tasks $task_item - ns_log Notice "Begin earliest_start($task_item): $earliest_start($task_item)" + # ns_log Notice "Begin earliest_start($task_item): $earliest_start($task_item)" } } # ------------------------------- # stop if we have no dependencies # ------------------------------- if {[llength $present_tasks] == 0} { - ns_log Notice "No tasks with dependencies" + # ns_log Notice "No tasks with dependencies" return [list] } - ns_log Notice "present_tasks: $present_tasks" + # ns_log Notice "present_tasks: $present_tasks" # ------------------------------------------------------ # figure out the earliest start and finish times @@ -450,7 +553,7 @@ foreach task_item $present_tasks { - ns_log Notice "this task_item: $task_item" + # ns_log Notice "this task_item: $task_item" # ----------------------------------------------------- # some tasks may already have earliest_start filled in @@ -460,7 +563,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 = @@ -484,10 +587,10 @@ # 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)" - ns_log Notice \ - " earliest_finish($task_item): $earliest_finish($task_item)" + # ns_log Notice \ + # " earliest_start ($task_item): $earliest_start($task_item)" + # ns_log Notice \ + # " earliest_finish($task_item): $earliest_finish($task_item)" } @@ -500,7 +603,7 @@ } } - ns_log Notice "future tasks: $future_tasks" + # ns_log Notice "future tasks: $future_tasks" set present_tasks $future_tasks } @@ -513,7 +616,7 @@ foreach task_item $task_list { - ns_log Notice "*Earliest start ($task_item): $earliest_start($task_item)" + # ns_log Notice "*Earliest start ($task_item): $earliest_start($task_item)" if {$max_earliest_finish < $earliest_finish($task_item)} { set max_earliest_finish $earliest_finish($task_item) } @@ -523,8 +626,16 @@ # ----------------------------------------------------------------- # Now compute latest_start and latest_finish dates. # Note the latest_finish dates may be set to an arbitrary deadline. + # Also note that it is possible for a project to be ongoing. + # In that case, the latest_start and latest_finish dates should + # be set to null. # ----------------------------------------------------------------- - + # If these represent the dependency hierarchy: + # 2155 + # / | \ + # 2161 2173 2179 + # | | + # 2167 2195 # ---------------------------------------------------------------------- # we want to go through and fill in all the values for latest start # and latest_finish. @@ -538,13 +649,42 @@ # add latest_finish values for. We call these lists # present_tasks and future_tasks # ---------------------------------------------------------------------- + # Here's a description of the algorithm. + # 1. The algorithm starts with those tasks that don't have other + # tasks depending on them. + # + # So in the example above, we'll start with + # present_tasks: 2167 2173 2195 + # future tasks: + # + # 2. While we make the present_tasks list, we store latest_start + # and latest_finish information for each of those tasks. If the + # project is ongoing, then we also keep track of tasks that have + # no latest_start or latest_finish. We keep this in the + # ongoing_task(task_id) array. If is exists, then we know that + # that task is an ongoing task, so no deadline will exist for it. + # + # 3. Stop if we don't have any dependencies + # + # 4. Then we get into a loop. + # While there are present_tasks: + # Create the future_tasks list + # For each present task: + # If the task has a dependent task: + # Go through these dependent tasks: + # If the dependent task is ongoing don't defer + # If the dependent task doesn't have LS set, + # then defer, and add to future_tasks list + # Otherwise set the LS value for that task + # If there are no deferals, get the minimum LS of + # dependents, set LF + # Add the dependent tasks to the future_tasks + # Set present_tasks equal to future_tasks, clear future_tasks + + # ---------------------------------------------------------------------- # The biggest problem with this algorithm is that you can have items at - # two different levels in the hierarchy. For example, - # 2155 - # / | \ - # 2161 2173 2179 - # | | - # 2167 2195 + # two different levels in the hierarchy. + # # if you trace through this algorithm, you'll see that we'll get to 2155 # before 2161's values have been set, which can cause an error. The # solution we arrive at is to defer to the future_tasks list any item @@ -572,27 +712,53 @@ # hard deadlines set. if {[info exists latest_finish($task_item)]} { - if {$end_date_j < $latest_finish($task_item)} { - set latest_finish($task_item) $end_date_j + # if the project needs to be completed before the + # actual hard deadline, then the project deadline + # has precedence. However, sometimes the project is + # ongoing, so we have to make sure that there actually + # is an end_date_j + if {![empty_string_p end_date_j]} { + if {$end_date_j < $latest_finish($task_item)} { + 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 [latest_start $latest_finish($task_item) $activity_time($task_item) $hours_day] + # we also set the latest_start date + set late_start_temp \ + [latest_start \ + -end_date_j $latest_finish($task_item) \ + -hours_to_complete $activity_time($task_item) \ + -hours_day $hours_day] + if {$late_start_temp < $latest_start($task_item)} { set latest_start($task_item) $late_start_temp } } 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) [latest_start $latest_finish($task_item) $activity_time($task_item) $hours_day] - } + # this section is for items that have no solid + # deadline, but also have no items dependent on them + # we either set the latest start and finish of the item or + # we specify that the task is an ongoing task + if {[empty_string_p $end_date_j]} { + set ongoing_task($task_item) true + ns_log Notice "NSDBAHNITD: end_date_j was empty ti:$task_item" + } else { + set latest_finish($task_item) $end_date_j + + set latest_start($task_item) \ + [latest_start \ + -end_date_j $latest_finish($task_item) \ + -hours_to_complete $activity_time($task_item) \ + -hours_day $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)" + # 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)" } @@ -633,70 +799,131 @@ # --------------------------------------------- # set the latest_start for this task = - # min(latest_start(i+1) - activity_time(i) + # min(latest_start(i+1) - activity_time(i)) # # (i+1 means an item that depends on this task) # (i means this task) # --------------------------------------------- + # we set this to the end date, and then move it back + # as we find dependent items that have earlier + # latest_start dates. The problem is that the + # end_date_j is empty when there is no deadline. + # So we need to remember that min_latest_start can + # be an empty value set min_latest_start $end_date_j - + foreach dependent_item $dependent($task_item) { + + if {[exists_and_not_null ongoing_task($dependent_item)]} { + set defer_p f + set my_latest_start "" + ns_log Notice "ongoing_task, no defer" + + } elseif {![exists_and_not_null latest_start($dependent_item)]} { + # we defer the task if the dependent item has no + # latest_start date set - 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 { + if {[info exists defer_count($task_item)]} { + incr defer_count($task_item) + } else { + set defer_count($task_item) 1 + } - #set my_latest_start [expr $latest_start($dependent_item) - [expr $activity_time($dependent_item) / double($hours_day)]] + # we use a magic number here. + # basically, we don't want to defer the + # item forever. Ideally, this should + # be cleaned up better. Defering is necessary + # given this algorithm, but there are + # times when you don't want to defer. + # This is hackish, and I'm embarrased, but on + # a deadline. :( + if {$defer_count($task_item) > 5} { + set defer_p f + ns_log Notice " no defer because defer count exceeded" + } else { + lappend future_tasks $task_item + ns_log Notice " defer" + set defer_p t + } + - 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" + } else { + + # the dependent item has a deadline + + set my_latest_start \ + [latest_start \ + -end_date_j $latest_start($dependent_item) \ + -hours_to_complete $activity_time($task_item) \ + -hours_day $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 } - + set defer_p f } + } - + if {[string equal $defer_p f]} { - + # we check that latest_start doesn't already exist # which it might for hard-deadlines if {[exists_and_not_null latest_start($task_item)]} { if {$min_latest_start < $latest_start($task_item)} { set latest_start($task_item) $min_latest_start } } else { + + # so this task has no hard deadline. + # We now set the value to the minimum of the + # dependent tasks. Note that if the dependent + # tasks all have no hard deadlines, and the + # project is ongoing, then the value will be + # set to "" + set latest_start($task_item) $min_latest_start } 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) - } + # we now set the latest finish. Ongoing tasks set + # the latest finish to empty + if {[empty_string_p $latest_start($task_item)]} { + set temp_lf "" } else { - set latest_finish($task_item) $temp + set temp_lf [my_latest_finish $min_latest_start $activity_time($task_item) $hours_day] } + # if there is already a hard deadline for this + # task, then we check whether temp_lf is earlier, + # and set it to temp_lf if so + + if {[empty_string_p $temp_lf]} { + set latest_finish($task_item) "" + } else { + if {[exists_and_not_null latest_finish($task_item)]} { + if {$temp_lf < $latest_finish($task_item)} { + set latest_finish($task_item) $temp_lf + } + } else { + set latest_finish($task_item) $temp_lf + } + } + ns_log Notice \ " latest_start ($task_item): $latest_start($task_item)" ns_log Notice \ " latest_finish($task_item): $latest_finish($task_item)" } else { ns_log Notice "Deferring $task_item" } - } + } # ------------------------------- # add to list of tasks to process @@ -716,14 +943,22 @@ # set up latest start date for project # ---------------------------------------------- - set min_latest_start $end_date_j + if {[empty_string_p $end_date_j]} { + set min_latest_start "" + set max_earliest_finish "" + } else { + set min_latest_start $end_date_j + + foreach task_item $task_list { - foreach task_item $task_list { - - ns_log Notice "*Latest start ($task_item): $latest_start($task_item)" - if {$min_latest_start > $latest_start($task_item)} { - set max_earliest_finish $earliest_finish($task_item) + ns_log Notice "*Latest start ($task_item): $latest_start($task_item)" + if {$min_latest_start > $latest_start($task_item)} { + set max_earliest_finish $earliest_finish($task_item) + } } + + set max_earliest_finish "J[expr floor([set max_earliest_finish])]" + set min_latest_start "J[expr floor([set min_latest_start])]" } @@ -736,6 +971,21 @@ # this is very inefficient and stupid foreach task_item $task_list { + set es "J[expr ceil( [set earliest_start($task_item)])]" + set ef "J[expr ceil( [set earliest_finish($task_item)])]" + + if {[exists_and_not_null latest_start($task_item)]} { + set ls "J[expr floor([set latest_start($task_item)])]" + } else { + set ls "" + } + + if {[exists_and_not_null latest_finish($task_item)]} { + set lf "J[expr floor($latest_finish($task_item))]" + } else { + set lf "" + } + db_dml update_task { } } @@ -749,7 +999,7 @@ -ad_proc -public project_manager::project::compute_parent_status {project_item_id} { +ad_proc -public pm::project::compute_parent_status {project_item_id} { When a project is updated, or a task updated within a project, we need to update all the projects higher in the hierarchy. @@ -779,3 +1029,4 @@ return $return_code } + Index: openacs-4/contrib/packages/project-manager/tcl/task-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/tcl/Attic/task-procs-postgresql.xql,v diff -u -r1.1.2.3 -r1.1.2.4 --- openacs-4/contrib/packages/project-manager/tcl/task-procs-postgresql.xql 6 Feb 2004 17:20:43 -0000 1.1.2.3 +++ openacs-4/contrib/packages/project-manager/tcl/task-procs-postgresql.xql 27 Feb 2004 22:46:13 -0000 1.1.2.4 @@ -3,16 +3,29 @@ postgresql7.3 - + + SELECT + i.item_id + FROM + cr_items i, + cr_revisions r + WHERE + i.item_id = r.item_id and + r.revision_id = :task_id + + + + + select status_id from pm_task_status where status_type = 'o' limit 1 - + select status_id from pm_task_status @@ -21,16 +34,37 @@ - + obviously broken select package_id from surveys where survey_id=:object_id - + + select pm_task__new_task_revision ( + :task_item_id, + :project_item_id, + :title, + :description, + [pm::project::util::datenvl -value $end_date -value_if_null "null" -value_if_not_null "to_timestamp('$end_date','YYYY MM DD HH24 MI SS')"], + :percent_complete, + :estimated_hours_work, + :estimated_hours_work_min, + :estimated_hours_work_max, + :actual_hours_worked, + :status_id, + current_timestamp, + :update_user, + :update_ip, + :package_id) + + + + + select pm_task__new_task_item ( :project_id, :title, 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.1.2.4 -r1.1.2.5 --- openacs-4/contrib/packages/project-manager/tcl/task-procs.tcl 6 Feb 2004 17:20:43 -0000 1.1.2.4 +++ openacs-4/contrib/packages/project-manager/tcl/task-procs.tcl 27 Feb 2004 22:46:13 -0000 1.1.2.5 @@ -10,25 +10,340 @@ } -namespace eval project_manager::task {} +namespace eval pm::task {} -ad_proc -public project_manager::task::default_status_open {} { +ad_proc -public pm::task::dependency_delete_all { + -task_item_id:required + +} { + Deletes all the dependencies of a task + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-02-23 + + @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" + return 1 +} + +ad_proc -public pm::task::dependency_add { + -task_item_id:required + -parent_id:required + -dependency_type:required + -project_item_id:required +} { + + Adds a dependency to a task, checking for loops in the process + +

+ + We make the assumption that the following is true: + +

    +
  • no loop is created if you depend on a task already present
  • +
  • therefore, if you add a task without creating a loop in the + newly created tasks, you are safe.
  • +
+ + We check that the new items don't depend on each other by + following them if they loop more than the number of tasks in the + project, then we have a loop + +

+ the way we check for a loop is to follow the dependencies + until we get to a task that has already been created. + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-02-23 + + @param task_item_id The task that is trying to create a + dependency. Of course this means that the task has already been + created. + + @param parent_id The task that we would like to create a + dependency on. (item_id for task, of course) + + @param dependency_type Type of dependency, from pm_dependency_types + + @param project_item_id The project's item_id. All dependencies are + created within this project + + @return + + @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 loop_limit [llength $project_tasks] + + 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 ", "]) + " { + lappend dep_list d-$dep_task-$dep_task_parent + } + + # are there any loops? + lappend dep_list d-$task_item_id-$parent_id + + foreach ti $project_tasks { + set task_state($ti) 0 + } + nsv_array set task_node_status [array get task_state] + + + set valid_p [pm::task::verify_no_loops \ + -current_task $task_item_id \ + -dependency_list $dep_list] + + ns_log debug "LOOPS? $valid_p" + #set passes_p f + #set my_task $task_item_id + #set my_parent $parent_id + + #while {$loop_limit >= 0} { + + #if {[exists_and_not_null dep_parent($my_task)]} { + # set my_task $dep_parent($my_task) + # } else { + # set passes_p t + # break + # } + # + # set loop_limit [expr $loop_limit - 1] + #} + } + + #ns_write "$loops_p" + #ad_script_abort + + if {[string equal $valid_p "TRUE"]} { + # 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')" + + } else { + ns_log Notice "Task $task_item_id was not added due to looping" + } + +} + + +ad_proc -private pm::task::verify_no_loops { + {-current_task:required} + {-dependency_list:required} +} { + Based on the dag_dfs algorithm at http://wiki.tcl.tk/3716 + +

+ + Determines if adding in the additional dependency would create + an cyclical graph or not + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-02-25 + + @param project_task_list + + @param current_task + + @param dependency_list a list of dependencies, each of the form + d-n1-n2 where n1 is the child and n2 is the parent. The initial + call to this function should include the proposed addition in + this list. + + @return TRUE if no loops, FALSE if the proposed additon would add loops + + @error +} { + + ns_log Notice "in verify_no_loops current_task: $current_task dependency_list $dependency_list" + + set return_val "" + + array set task_state [nsv_array get task_node_status] + ns_log Notice " btw: $current_task -> $task_state($current_task)" + + set task_state($current_task) 1 + + ns_log Notice " set state $current_task -> 1" + nsv_array set task_node_status [array get task_state] + + foreach arc $dependency_list { + regexp {d-(.*)-(.*)} $arc match child parent + + # only walk to dependencies from the current task + if {[string equal $child $current_task]} { + + set tNode $parent + + array set task_state [nsv_array get task_node_status] + + set used $task_state($tNode) + + ns_log Notice "Used is $used" + + if {[string equal $used 1]} { + ns_log Notice "we return FALSE" + return FALSE + } + + set return_val [pm::task::verify_no_loops \ + -current_task $parent \ + -dependency_list $dependency_list + ] + + ns_log Notice " return_val $return_val" + + if {[string equal $return_val FALSE]} { + ns_log Notice "we return FALSE" + return FALSE + } + } + + } + + array set task_state [nsv_array get task_node_status] + ns_log Notice " btw task_state($current_task) = $task_state($current_task)" + set task_state($current_task) 2 + ns_log Notice " set task_state($current_task) = 2" + nsv_array set task_node_status [array get task_state] + + return TRUE +} + + + +ad_proc -public pm::task::get_task_item_id { + -task_id:required +} { + Returns the task_item_id (item_id) when given the task_id (revision_id) + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-02-19 + + @param task_id The revision item + + @return task_item_id + + @error +} { + set return_val [db_string get_task_item_id { }] + + return $return_val +} + +ad_proc -public pm::task::default_status_open {} { Returns the default status value for open tasks } { set return_val [db_string get_default_status_open { }] return $return_val } -ad_proc -public project_manager::task::default_status_closed {} { +ad_proc -public pm::task::default_status_closed {} { Returns the default status value for closed tasks } { set return_val [db_string get_default_status_closed { }] return $return_val } -ad_proc -public project_manager::task::new { + +ad_proc -public pm::task::update { + -task_item_id:required + -project_item_id:required + -title:required + -description:required + -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 +} { + + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-02-23 + + @param task_item_id + + @param project_item_id + + @param title + + @param description + + @param end_date + + @param percent_complete + + @param estimated_hours_work + + @param estimated_hours_work_min + + @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 + + @param package_id + + @return new revision_id for the task + + @error +} { + if {$percent_complete >= 100} { + set status_id [pm::task::default_status_closed] + } + + if {![exists_and_not_null status_id]} { + set status_id [pm::task::default_status_open] + } + + set return_val [db_exec_plsql new_task_revision { *SQL }] + + return $return_val +} + + + +ad_proc -public pm::task::new { -project_id:required -title:required {-description ""} @@ -44,7 +359,7 @@ -package_id:required } { if {![exists_and_not_null status_id]} { - set status_id [project_manager::task::default_status_open] + set status_id [pm::task::default_status_open] } set return_val [db_exec_plsql new_task_item { *SQL }] @@ -53,7 +368,7 @@ } -ad_proc -public project_manager::task::get_url { +ad_proc -public pm::task::get_url { object_id } { # set package_id [db_string get_package_id {}] @@ -63,9 +378,46 @@ return "/project-manager/task-one?task_id=$object_id" } -ad_proc -public project_manager::task::process_reply { +ad_proc -public pm::task::process_reply { reply_id } { } + +ad_proc -public pm::task::slack_time { + -earliest_start_j:required + -today_j:required + -latest_start_j:required +} { + + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-02-20 + + @param earliest_start_j Earliest start date, Julian + + @param today_j today's date, in Julian + + @param latest_start_j Latest start date, in Julian + + @return Slack days + + @error +} { + if { \ + [exists_and_not_null earliest_start_j] && \ + [exists_and_not_null latest_start_j]} { + + if {$earliest_start_j < $today_j} { + set slack_time "[expr $latest_start_j - $today_j] days" + } else { + set slack_time "[expr $latest_start_j - $earliest_start_j] days" + } + + } else { + set slack_time "n/a" + } + +} + Index: openacs-4/contrib/packages/project-manager/www/add-edit-2-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/add-edit-2-postgresql.xql,v diff -u -r1.1.2.2 -r1.1.2.3 --- openacs-4/contrib/packages/project-manager/www/add-edit-2-postgresql.xql 4 Feb 2004 20:17:19 -0000 1.1.2.2 +++ openacs-4/contrib/packages/project-manager/www/add-edit-2-postgresql.xql 27 Feb 2004 22:46:13 -0000 1.1.2.3 @@ -4,21 +4,20 @@ SELECT p.item_id as project_item_id, - p.project_id, p.title as project_name, p.description FROM pm_projectsx p WHERE - p.project_id = :project_id + p.project_id = :old_project_id UPDATE pm_projects set - + WHERE project_id = :project_id Index: openacs-4/contrib/packages/project-manager/www/add-edit-2.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/add-edit-2.adp,v diff -u -r1.1.2.1 -r1.1.2.2 --- openacs-4/contrib/packages/project-manager/www/add-edit-2.adp 13 Dec 2003 01:19:54 -0000 1.1.2.1 +++ openacs-4/contrib/packages/project-manager/www/add-edit-2.adp 27 Feb 2004 22:46:13 -0000 1.1.2.2 @@ -3,5 +3,5 @@ @title@

- +
Index: openacs-4/contrib/packages/project-manager/www/add-edit-2.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/add-edit-2.tcl,v diff -u -r1.1.2.3 -r1.1.2.4 --- openacs-4/contrib/packages/project-manager/www/add-edit-2.tcl 5 Feb 2004 23:57:49 -0000 1.1.2.3 +++ openacs-4/contrib/packages/project-manager/www/add-edit-2.tcl 27 Feb 2004 22:46:13 -0000 1.1.2.4 @@ -17,6 +17,7 @@ } { project_id:integer,optional + {old_project_id ""} {project_item_id ""} {project_name ""} {description ""} @@ -28,6 +29,12 @@ } + +# this is necessary for new projects +if {![exists_and_not_null old_project_id]} { + set old_project_id $project_id +} + # --------------------------------------------------------------- # # the unique identifier for this package set package_id [ad_conn package_id] @@ -69,6 +76,8 @@ } } \ + -validate { + } \ -select_query_name project_query \ -on_submit { @@ -78,7 +87,7 @@ } \ -new_data { - ad_returnredirect "one?[export_url_vars project_item_id project_id]" + ad_returnredirect "one?[export_url_vars project_item_id]" ad_script_abort } -edit_data { @@ -87,7 +96,7 @@ } -after_submit { - ad_returnredirect "one?[export_url_vars project_id]" + ad_returnredirect "one?[export_url_vars project_item_id]" ad_script_abort } Index: openacs-4/contrib/packages/project-manager/www/add-edit-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/add-edit-postgresql.xql,v diff -u -r1.9.2.3 -r1.9.2.4 --- openacs-4/contrib/packages/project-manager/www/add-edit-postgresql.xql 9 Feb 2004 16:27:59 -0000 1.9.2.3 +++ openacs-4/contrib/packages/project-manager/www/add-edit-postgresql.xql 27 Feb 2004 22:46:13 -0000 1.9.2.4 @@ -2,32 +2,31 @@ - SELECT - p.item_id as project_item_id, - p.parent_id, - p.project_id, - p.title as project_name, - p.project_code, - p.goal, - p.description, - p.status_id, - to_char(p.planned_start_date,'YYYY MM DD') as planned_start_date, - to_char(p.planned_end_date,'YYYY MM DD') as planned_end_date, - p.ongoing_p - FROM - pm_projectsx p - WHERE - p.item_id = :project_item_id and - p.project_id = :project_id + SELECT + p.item_id as project_item_id, + p.parent_id, + p.project_id, + p.title as project_name, + p.project_code, + p.goal, + p.description, + p.customer_id, + p.status_id, + to_char(p.planned_start_date,'YYYY MM DD') as planned_start_date, + to_char(p.planned_end_date,'YYYY MM DD') as planned_end_date, + p.ongoing_p + FROM + pm_projectsx p + WHERE + p.item_id = :project_item_id and + p.project_id = :project_id SELECT current_timestamp - FROM - pm_projects @@ -45,6 +44,7 @@ null, :ongoing_p, :status_id, + :customer_id, now(), :user_id, :peeraddr, @@ -77,17 +77,6 @@
- - - SELECT - p.item_id as project_item_id - FROM - pm_projectsx p - WHERE - p.project_id = :project_id - - - SELECT Index: openacs-4/contrib/packages/project-manager/www/add-edit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/add-edit.adp,v diff -u -r1.4 -r1.4.2.1 --- openacs-4/contrib/packages/project-manager/www/add-edit.adp 10 Nov 2003 19:34:54 -0000 1.4 +++ openacs-4/contrib/packages/project-manager/www/add-edit.adp 27 Feb 2004 22:46:13 -0000 1.4.2.1 @@ -1,7 +1,8 @@ + @context_bar;noquote@ @title@
- +
Index: openacs-4/contrib/packages/project-manager/www/add-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/add-edit.tcl,v diff -u -r1.12.2.7 -r1.12.2.8 --- openacs-4/contrib/packages/project-manager/www/add-edit.tcl 5 Feb 2004 23:57:49 -0000 1.12.2.7 +++ openacs-4/contrib/packages/project-manager/www/add-edit.tcl 27 Feb 2004 22:46:13 -0000 1.12.2.8 @@ -45,13 +45,21 @@ set use_project_customizations_p [parameter::get -parameter "UseProjectCustomizationsP" -default "0"] +set ongoing_by_default_p [parameter::get -parameter "OngoingByDefaultP" -default "f"] + +if {[exists_and_not_null project_item_id] && ![exists_and_not_null project_id]} { + set project_id [pm::project::get_project_id -project_item_id $project_item_id] +} + + if {[exists_and_not_null project_id]} { set title "Edit a $project_term_lower" set context_bar [ad_context_bar "Edit $project_term"] # permissions permission::require_permission -party_id $user_id -object_id $package_id -privilege write + } else { set title "Add a $project_term_lower" set context_bar [ad_context_bar "New $project_term"] @@ -91,23 +99,22 @@ {planned_start_date:date,to_sql(linear_date) {label "Starts"} - {format "MONTH DD YYYY"} - {value {[util::date acquire clock [clock scan $planned_start_date]]}} + {value $planned_start_date} {today} {help} } {planned_end_date:date,to_sql(linear_date) {label "Deadline"} - {format "MONTH DD YYYY"} - {value {[util::date acquire clock [clock scan $planned_end_date]]}} + {value $planned_end_date} {today} {help} } {ongoing_p:text(select) {label "Project is ongoing?"} - {options {{"No" "f"} {"Yes" "t"}} {value $ongoing_p}} + {options {{"No" f} {"Yes" t}}} + {value $ongoing_p} {help_text "If yes, then this project has no deadline"} } @@ -116,9 +123,21 @@ {options {[db_list_of_lists get_status_codes { }]}} } - } + } \ + -new_request { + + if {[string equal $ongoing_by_default_p t]} { + set ongoing_p t + } + set planned_end_date [util::date acquire clock [clock scan $planned_end_date]] + set planned_start_date [util::date acquire clock [clock scan $planned_start_date]] + + } + + + if {[exists_and_not_null project_id]} { if {![empty_string_p [category_tree::get_mapped_trees $package_id]]} { ad_form -extend -name add_edit -form { @@ -171,28 +190,27 @@ } -new_data { + set project_id [pm::project::new \ + -project_name $project_name \ + -project_code $project_code \ + -parent_id $parent_id \ + -goal $goal \ + -description $description \ + -planned_start_date $planned_start_date \ + -planned_end_date $planned_end_date \ + -actual_start_date "" \ + -actual_end_date "" \ + -ongoing_p $ongoing_p \ + -status_id $status_id \ + -organization_id $customer_id \ + -creation_date "" \ + -creation_user $user_id \ + -creation_ip $peeraddr \ + -package_id $package_id + ] - set project_id [project_manager::project::new \ - -project_name $project_name \ - -project_code $project_code \ - -parent_id $parent_id \ - -goal $goal \ - -description $description \ - -planned_start_date $planned_start_date \ - -planned_end_date $planned_end_date \ - -actual_start_date "" \ - -actual_end_date "" \ - -ongoing_p $ongoing_p \ - -status_id $status_id \ - -organization_id $customer_id \ - -creation_date "" \ - -creation_user $user_id \ - -creation_ip $peeraddr \ - -package_id $package_id - ] + set project_item_id [pm::project::get_project_item_id -project_id $project_id] - set project_item_id [db_string get_item_id { }] - if {[exists_and_not_null category_ids]} { category::map_object -remove_old -object_id $project_item_id $category_ids } @@ -206,18 +224,21 @@ } } -edit_data { + + # we need to pass the old_project_id to add-edit-2.tcl because + # the new revision will not have any of the custom values in + # it until it is edited. So we need to pull in these values + set old_project_id $project_id -ns_log Notice "edit" set project_id [db_exec_plsql new_project_revision { *SQL* }] - project_manager::project::compute_parent_status $project_item_id + pm::project::compute_parent_status $project_item_id category::map_object -remove_old -object_id $project_item_id $category_ids } -after_submit { -ns_log Notice "after_submit" if {$use_project_customizations_p} { - ad_returnredirect "add-edit-2?[export_url_vars project_id]" + ad_returnredirect "add-edit-2?[export_url_vars project_id old_project_id]" ad_script_abort } else { ad_returnredirect "one?[export_url_vars project_id]" Index: openacs-4/contrib/packages/project-manager/www/index-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/index-postgresql.xql,v diff -u -r1.8.2.6 -r1.8.2.7 --- openacs-4/contrib/packages/project-manager/www/index-postgresql.xql 5 Feb 2004 23:57:49 -0000 1.8.2.6 +++ openacs-4/contrib/packages/project-manager/www/index-postgresql.xql 27 Feb 2004 22:46:13 -0000 1.8.2.7 @@ -1,8 +1,8 @@ -postgresql7.2 + postgresql7.3 - + SELECT p.item_id as project_item_id, @@ -23,10 +23,13 @@ to_char(p.estimated_finish_date, 'MM/DD/YY') as estimated_finish_date, to_char(p.earliest_finish_date, 'MM/DD/YY') as earliest_finish_date, to_char(p.latest_finish_date, 'MM/DD/YY') as latest_finish_date, - case when o.name is null then '--no customer--' else o.name end as customer_name, - o.organization_id + case when o.name is null then '--no customer--' else o.name + end as customer_name, + case when f.name is null then '--no facility--' else f.name end as facility_name, + o.organization_id as customer_id FROM pm_projectsx p - LEFT JOIN organizations o ON p.customer_id = o.organization_id + LEFT JOIN organizations o ON p.customer_id = + o.organization_id LEFT JOIN ( select om.category_id, Index: openacs-4/contrib/packages/project-manager/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/index.adp,v diff -u -r1.17.2.2 -r1.17.2.3 --- openacs-4/contrib/packages/project-manager/www/index.adp 13 Dec 2003 01:19:54 -0000 1.17.2.2 +++ openacs-4/contrib/packages/project-manager/www/index.adp 27 Feb 2004 22:46:13 -0000 1.17.2.3 @@ -9,18 +9,18 @@ - + - @category_select;noquote@ + - - - + - + @category_select;noquote@ + + Index: openacs-4/contrib/packages/project-manager/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/index.tcl,v diff -u -r1.9.2.8 -r1.9.2.9 --- openacs-4/contrib/packages/project-manager/www/index.tcl 6 Feb 2004 17:20:43 -0000 1.9.2.8 +++ openacs-4/contrib/packages/project-manager/www/index.tcl 27 Feb 2004 22:46:13 -0000 1.9.2.9 @@ -1,7 +1,7 @@ ad_page_contract { Main view page for projects. - + @author jader@bread.com @author ncarroll@ee.usyd.edu.au (on first version that used CR) @creation-date 2003-05-15 @@ -19,6 +19,7 @@ orderby_project:optional {status_id:integer,optional} category_id:multiple,optional + {format "normal"} } -properties { context:onevalue @@ -61,28 +62,29 @@ # set default values if {![exists_and_not_null status_id]} { - set status_id [project_manager::project::default_status_open] + set status_id [pm::project::default_status_open] } # Categories are arranges into category trees. # Set up an array for each tree. The array contains the category for each tree -db_foreach get_choices " -select -t.name as cat_name, -t.category_id as cat_id, -tm.tree_id -from -category_tree_map tm, -categories c, -category_translations t -where -c.tree_id = tm.tree_id and -c.category_id = t.category_id and -tm.object_id = :package_id and -c.deprecated_p = 'f' -order -by t.name" { +db_foreach get_choices { + select + t.name as cat_name, + t.category_id as cat_id, + tm.tree_id + from + category_tree_map tm, + categories c, + category_translations t + where + c.tree_id = tm.tree_id and + c.category_id = t.category_id and + tm.object_id = :package_id and + c.deprecated_p = 'f' + order + by t.name +} { lappend category_choices($tree_id) [list $cat_name $cat_id] } @@ -92,17 +94,18 @@ set category_select "" -foreach tree_list [db_list_of_lists get_category_trees " -select -tt.name as tree_name, -tt.tree_id -from -category_tree_map tm, -category_tree_translations tt -where -tm.object_id = :package_id and -tm.tree_id = tt.tree_id"] { - +foreach tree_list [db_list_of_lists get_category_trees { + select + tt.name as tree_name, + tt.tree_id + from + category_tree_map tm, + category_tree_translations tt + where + tm.object_id = :package_id and + tm.tree_id = tt.tree_id +}] { + set tree_name [lindex $tree_list 0] set tree_id [lindex $tree_list 1] @@ -139,8 +142,8 @@ customer_name { label "Customer" display_template " - @projects.customer_name@@projects.customer_name@ - " +@projects.customer_name@@projects.customer_name@ +" } project_name { label "Project name" @@ -224,6 +227,33 @@ default_direction asc } } \ + -formats { + normal { + label "Table" + layout table + row { + project_name {} + customer_name {} + category_id {} + earliest_finish_date {} + latest_finish_date {} + actual_hours_completed {} + } + } + csv { + label "CSV" + output csv + page_size 0 + row { + project_name {} + customer_name {} + category_id {} + earliest_finish_date {} + latest_finish_date {} + actual_hours_completed {} + } + } + } \ -orderby_name orderby_project \ -html { width 100% @@ -236,4 +266,27 @@ } +# This spits out the CSV if we happen to be in CSV layout + +if {[string equal $format csv]} { + #set csv [list::write_output -name pan] + #set outputheaders [ns_conn outputheaders] + #ns_set cput $outputheaders "Content-Disposition" "attachment; filename=pan.csv" + #doc_return 200 "application/text" "$csv" + + # set csv [list::write_output -name projects] + + set outputheaders [ns_conn outputheaders] + ns_set cput $outputheaders "Content-Disposition" "attachment; filename=projects.xls" + + # ns_log Notice "csv: $csv" + + list::write_output -name projects + + # doc_return 200 application/vnd.ms-excel $csv + # ns_return 200 application/vnd.ms-excel $csv + +} + + # ------------------------- END OF FILE ------------------------- # Index: openacs-4/contrib/packages/project-manager/www/one-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/one-postgresql.xql,v diff -u -r1.19.2.5 -r1.19.2.6 --- openacs-4/contrib/packages/project-manager/www/one-postgresql.xql 5 Feb 2004 23:57:49 -0000 1.19.2.5 +++ openacs-4/contrib/packages/project-manager/www/one-postgresql.xql 27 Feb 2004 22:46:13 -0000 1.19.2.6 @@ -155,7 +155,8 @@ SELECT - p.customer_id + p.customer_id, + c.name as customer_name FROM pm_projectsx p LEFT JOIN organizations c ON p.customer_id = c.organization_id Index: openacs-4/contrib/packages/project-manager/www/one.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/one.adp,v diff -u -r1.27.2.6 -r1.27.2.7 --- openacs-4/contrib/packages/project-manager/www/one.adp 5 Feb 2004 23:57:49 -0000 1.27.2.6 +++ openacs-4/contrib/packages/project-manager/www/one.adp 27 Feb 2004 22:46:13 -0000 1.27.2.7 @@ -10,206 +10,215 @@
+ +
+ + + + -
+
- + -
+ + Edit + + @project_term@
- - + - + + +
- Edit -
@project_term@
-
- - - + + + -
+
Name@project.project_name@
+ + + + + + - - - + + + + + + + + + + + + +
Code@project.project_code@
Name@project.project_name@
Goal@project.goal@
Description@project.description@
+ + - - - Code - @project.project_code@ - - +

- - - Goal - @project.goal@ - - - + - - + -
Description@project.description@Dates
+ + + + + + + -
Start@project.planned_start_date@
+ + Earliest finish + + @project.earliest_finish_date@ + + + Ongoing + + -

+ + Deadline + + @project.planned_end_date@ + + + Ongoing + + - - - - + + + + + + + + + - - +
Dates
Latest finish@project.latest_finish_date@Ongoing
- - - - - + + + + - - - - - - - - +
Start@project.planned_start_date@
Hours completed@project.actual_hours_completed@ of @project.estimated_hours_total@
Earliest finish@project.earliest_finish_date@Ongoing
+
- - Deadline - - @project.planned_end_date@ - - - Ongoing - - +

+ + +

+ + + + + + + +
Project information
+ + + + + + +
Customer@custom.customer_name@
+
+ + +

+ + - - - - - - - + - + - - + -
Latest finish@project.latest_finish_date@OngoingCategories
Hours completed@project.actual_hours_completed@ of @project.estimated_hours_total@ + + + + +
+ +
    + + +
  • @categories:item@ + + +
+ +
+
- +

+ Add subproject + + Subprojects: + + + + +

-

- -

- - - - + - -
Project information
- - - - - -
Customer@custom.customer_name@
-
- - -

- - - - - - - - - -
Categories
- - -
- + + + + + + + + - - -
Tasks
+ +
    - - -
  • @categories:item@ - - +
  • +
    + Add + + + + Tasks + +
    +
+
-

- Add subproject -

- - Subprojects: - - - - - - - - - - - - - - -
Tasks
- - -
    -
  • -
    - Add - - - - Tasks - -
    -
  • -
-
- - - -
- +

- + - +

Index: openacs-4/contrib/packages/project-manager/www/one.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/one.tcl,v diff -u -r1.26.2.7 -r1.26.2.8 --- openacs-4/contrib/packages/project-manager/www/one.tcl 6 Feb 2004 17:20:43 -0000 1.26.2.7 +++ openacs-4/contrib/packages/project-manager/www/one.tcl 27 Feb 2004 22:46:13 -0000 1.26.2.8 @@ -205,16 +205,11 @@ 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]} { - if {$earliest_start_j < $today_j} { - set slack_time "[expr $latest_start_j - $today_j] days" - } else { - set slack_time "[expr $latest_start_j - $earliest_start_j] days" - } - } else { - set slack_time "n/a" - } - + set slack_time [pm::task::slack_time \ + -earliest_start_j $earliest_start_j \ + -today_j $today_j \ + -latest_start_j $latest_start_j] + } @@ -316,11 +311,14 @@ -multirow versions \ -key item_id \ -elements { - project_name { - label "Subject" + project_id { + label "Version" link_url_col item_url link_html { title "View this project version" } } + project_name { + label "Subject" + } planned_end_date { label "Deadline" } @@ -346,7 +344,7 @@ db_multirow -extend { item_url } versions project_versions { } { - set item_url [export_vars -base "one" -override {{project_item_id $item_id}} {project_item_id}] + set item_url [export_vars -base "one" -override {{project_item_id $item_id}} {project_id}] } @@ -358,8 +356,6 @@ db_1row custom_query { } -column_array custom - - # end of customizations Index: openacs-4/contrib/packages/project-manager/www/process-task-assign-add-edit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/process-task-assign-add-edit.adp,v diff -u -r1.2 -r1.2.2.1 --- openacs-4/contrib/packages/project-manager/www/process-task-assign-add-edit.adp 10 Nov 2003 19:34:54 -0000 1.2 +++ openacs-4/contrib/packages/project-manager/www/process-task-assign-add-edit.adp 27 Feb 2004 22:46:13 -0000 1.2.2.1 @@ -1,40 +1,52 @@ -@context_bar;noquote@ -@title@ + @context_bar;noquote@ + @title@ -
+
- + - + - - - - +
@tasks.one_line@
+ + + + + + - + + + + +
+ + + -
@tasks.one_line@
+ + + + + Error + + -
@tasks.description@
- - -
+
+
-
+

- + -

+ + + - - - - - - Index: openacs-4/contrib/packages/project-manager/www/process-task-assign-add-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/process-task-assign-add-edit.tcl,v diff -u -r1.6.2.5 -r1.6.2.6 --- openacs-4/contrib/packages/project-manager/www/process-task-assign-add-edit.tcl 5 Feb 2004 23:57:49 -0000 1.6.2.5 +++ openacs-4/contrib/packages/project-manager/www/process-task-assign-add-edit.tcl 27 Feb 2004 22:46:13 -0000 1.6.2.6 @@ -91,7 +91,7 @@ # currently hardcoded the number of assignments -for {set i 0} {$i <= 10} {incr i} { +for {set i 0} {$i <= 5} {incr i} { template::multirow append num $i } Index: openacs-4/contrib/packages/project-manager/www/task-add-edit-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/task-add-edit-postgresql.xql,v diff -u -r1.11.2.4 -r1.11.2.5 --- openacs-4/contrib/packages/project-manager/www/task-add-edit-postgresql.xql 6 Feb 2004 17:20:43 -0000 1.11.2.4 +++ openacs-4/contrib/packages/project-manager/www/task-add-edit-postgresql.xql 27 Feb 2004 22:46:13 -0000 1.11.2.5 @@ -9,7 +9,8 @@ t.estimated_hours_work, t.estimated_hours_work_min, t.estimated_hours_work_max, - d.dependency_id + d.dependency_id, + d.parent_task_id as process_parent_task FROM pm_process_task t LEFT JOIN pm_process_task_dependency d ON t.process_task_id = d.process_task_id WHERE @@ -26,7 +27,7 @@ :project_item_id, :p_task_title, :p_description, - [project_manager::project::util::datenvl -value [set end_date_$i] -value_if_null "null," -value_if_not_null "to_timestamp('[set end_date_$i]','YYYY MM DD HH24 MI SS'),"] + [pm::project::util::datenvl -value [set end_date_$i] -value_if_null "null," -value_if_not_null "to_timestamp('[set end_date_$i]','YYYY MM DD HH24 MI SS'),"] :p_percent, :p_work, :p_work_min, @@ -44,26 +45,22 @@ select current_timestamp - FROM - dual select t.task_revision_id, - t.title as task_title, - t.item_id, - t.description, - t.name, - to_char(t.end_date,'YYYY MM DD') as end_date, - t.percent_complete, - t.estimated_hours_work, - t.estimated_hours_work_min, - t.estimated_hours_work_max, - d.parent_task_id, - t.actual_hours_worked + t.title as my_task_title, + t.description as my_description, + to_char(t.end_date,'YYYY MM DD') as my_end_date, + t.percent_complete as my_percent_complete, + t.estimated_hours_work as my_estimated_work, + t.estimated_hours_work_min as my_estimated_work_min, + t.estimated_hours_work_max as my_estimated_work_max, + t.actual_hours_worked as my_actual_hours_worked, + d.parent_task_id as my_dependency FROM pm_tasks_revisionsx t, cr_items i LEFT JOIN pm_task_dependency d ON i.item_id = d.task_id @@ -113,15 +110,6 @@ - - - INSERT INTO pm_task_dependency - (dependency_id, task_id, parent_task_id, dependency_type) - VALUES - (:dependency_id, :this_task_id, :parent_task_id, :p_dep_type) - - - select Index: openacs-4/contrib/packages/project-manager/www/task-add-edit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/task-add-edit.adp,v diff -u -r1.10.2.2 -r1.10.2.3 --- openacs-4/contrib/packages/project-manager/www/task-add-edit.adp 10 Jan 2004 01:04:02 -0000 1.10.2.2 +++ openacs-4/contrib/packages/project-manager/www/task-add-edit.adp 27 Feb 2004 22:46:13 -0000 1.10.2.3 @@ -1,141 +1,212 @@ -@title;noquote@ -@context_bar;noquote@ + @title;noquote@ + @context_bar;noquote@ -

+
- +
- + - + - - - - - - + + + + + + - + - + Description:
+ + +
+ Error +
+
+

- + + Skip this task?
+
-

+ -
- -
 #@num.rownum@   #@num.rownum@  Subject:*
- -
Error -
-

+

Subject:*
+ + +
+ Error +
+
+

- Description:
- -
Error -
-

- - - - - - - - - - - + + + -
Work required:*
Min: hrs - - -
Error + + +
+ Error
+
+
Max: hrs - -
Error -
+
+ + + + - - - - - + + + - - - + + + + +
+ Error +
+ + + + + -
Work required:*
hrs + +
Min: + hrs - -
Error -
+ +
+ Error +
+
+
Max: + hrs -
-

- [i] - You must enter a number here (make your best guess)

+ +
+ hrs -

+ +
+ Error +
+ +

+ + + +
+

+ [i] + You must enter a number here (make your best + guess) +

+
-
- Deadline:
+

+ + - - Error + + - + + + + + + Error + + -
+ Deadline:
-

- [i] - You may optionally enter a hard deadline

-
- Dependency:
+ + + Error + + - - Error +

+ [i] + You may optionally enter a hard deadline +

+
+ Dependency: +
- - Error + + + Error + + -

- [i] - You may enter a @task_term_lower@ that needs to be completed before this @task_term_lower@

-
+

+ [i] + You may enter a @task_term_lower@ that needs to + be completed before this @task_term_lower@ +

+
- - - - - - - - -
Percent complete:
Hours worked:
- - - - - + - - +
+ + + + + + + + + + +
Percent complete: + + + + +
Hours worked: + + + + +
+
+ + + + + + + + + + - + + + + - + - + -<% ns_log Notice error: [export_vars formerror]%> + - - -
+ + + <% ns_log Notice error: [export_vars formerror]%> + + + +
Index: openacs-4/contrib/packages/project-manager/www/task-add-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/task-add-edit.tcl,v diff -u -r1.23.2.7 -r1.23.2.8 --- openacs-4/contrib/packages/project-manager/www/task-add-edit.tcl 6 Feb 2004 17:20:43 -0000 1.23.2.7 +++ openacs-4/contrib/packages/project-manager/www/task-add-edit.tcl 27 Feb 2004 22:46:13 -0000 1.23.2.8 @@ -1,4 +1,4 @@ -set debug 0 +set debug 1 if {[string equal $debug 1]} { ns_log notice task add edit page @@ -21,7 +21,7 @@ @return context_bar Context bar. @return title Page title. - @return num num is used as a multirow datasource to iterate over the ad_form elements + @return num A multirow datasource to iterate over the ad_form elements @return edit_p if t then we are editing. Used to show different portions of the form @param process_task_ids Specifies what process task ids were used if a process were used. We pass this on to future pages to determine things such as assignments @@ -33,8 +33,10 @@ @param task_id Specifies the item for the task (every revision of a task shares the same task_id) Also used as the key for the ad_form. For this reason, when editing, we have to pass in task_iid instead @param my_key if set, then ad_form knows that this is an edit @param task_title + @param skip_task_p Whether or not to skip this particular task. Used by processes, if t, then the task is not created @param process_id The process we're using to create this task @param use_uncertain_completion_times_p Whether or not to use PERT-style completion time uncertainty 1 = yes + @return using_process_p Lets the UI know if there is a process being used (t if so) } { my_key:integer,optional @@ -57,6 +59,8 @@ estimated_hours_work_max:array,optional dependency_type:array,optional dependency_task_id:array,optional + skip_task_p:array,optional + {using_process_p "f"} } -properties { @@ -65,8 +69,15 @@ num:multirow use_uncertain_completion_times_p:onevalue edit_p:onevalue + using_process_p:onevalue } -validate { + project_exists { + if {![exists_and_not_null project_item_id] && \ + ![exists_and_not_null project_id]} { + ad_complain + } + } number_is_in_range -requires {number:integer} { # todo: make 100 a parameter if {$number < 1 || $number > 100} { @@ -79,6 +90,7 @@ } } } -errors { + project_exists {You must enter a project} number_is_in_range {Number must be between 1 and 100} percent_is_in_range {Percent completed must be between 0 and 100} } @@ -88,11 +100,15 @@ set user_id [ad_maybe_redirect_for_registration] set package_id [ad_conn package_id] + +# --------------------------------------------------------------- # # terminology +# --------------------------------------------------------------- # set project_term [parameter::get -parameter "ProjectName" -default "Project"] 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 "1"] +# --------------------------------------------------------------- # if {![exists_and_not_null project_id]} { @@ -110,35 +126,47 @@ set process_tasks [list] if {[exists_and_not_null process_id]} { + + # we need the ADP page to know we're using processes, so we can + # modify the interface a little bit + set using_process_p t + db_foreach get_process_tasks { } { set one_line_v($process_tid) $one_line set description_v($process_tid) $description set estimated_hours_work_v($process_tid) $estimated_hours_work set estimated_hours_work_min_v($process_tid) $estimated_hours_work_min set estimated_hours_work_max_v($process_tid) $estimated_hours_work_max - set dependency_v($process_tid) $dependency_id + set dependency_v($process_tid) $process_parent_task lappend process_tasks $process_tid } set number [llength $process_tasks] } +# --------------------------------------------------------------- # + + + # we use this to get around the lack of a hidden multiple in ad_form set task_id_pass [string map {"-" " "} $task_id] set task_id $task_id_pass + +# --------------------------------------------------------------- # +# Create a multirow: num +# --------------------------------------------------------------- # + if {![ad_form_new_p -key task_id]} { + # ----------------------------------------------------- # Editing! # ----------------------------------------------------- # create a multirow we can use to iterate # we also set the number variable for future use # ----------------------------------------------------- template::multirow create num number - # TODO:get task IDS - # - set i 1 set number 0 foreach tid $task_id { @@ -160,8 +188,8 @@ set edit_p f } -ns_log Notice "Edit_p: $edit_p number: $number " +# ------------------------------------------------------- # # The evilest hack of all time. # ------------------------------------------------------- # This is a workaround the fact that using multiple dates @@ -177,6 +205,7 @@ # the SQL function that creates the new tasks. This works. I'm # sure there must be a better way to do it, but my posting on # the forums didn't result in any other suggestions. +# ------------------------------------------------------- # if {[info exists end_date]} { @@ -201,21 +230,40 @@ } } -# permissions and more +# --------------------------------------------------------------- # +# permissions and title setup, etc +# we should update the permissions to not just use package_id +# --------------------------------------------------------------- # if {[exists_and_not_null task_id]} { + set title "Edit a $task_term_lower" set context_bar [ad_context_bar [list "one?item_id=$project_item_id&project_id=$project_id" "One $project_term"] "Edit $task_term"] - permission::require_permission -party_id $user_id -object_id $package_id -privilege write + permission::require_permission \ + -party_id $user_id \ + -object_id $package_id \ + -privilege write + } else { + set title "Add a $task_term_lower" set context_bar [ad_context_bar [list "one?item_id=$project_item_id&project_id=$project_id" "One $project_term"] "New $task_term"] - permission::require_permission -party_id $user_id -object_id $package_id -privilege create + permission::require_permission \ + -party_id $user_id \ + -object_id $package_id \ + -privilege create + } # we use this to pass through the task_ids set task_id_pass [string map {" " "-"} $task_id] + + +# --------------------------------------------------------------- # +# Begin our form +# --------------------------------------------------------------- # + ad_form -name add_edit -form { my_key:key(acs_object_id_seq) @@ -246,17 +294,18 @@ set i 1 - db_foreach get_old_tasks { } { + db_foreach get_old_tasks { *SQL* } { - set task_title_arr($i) $task_title - set description_arr($i) $description - set estimated_hours_arr($i) $estimated_hours_work - set estimated_hours_min_arr($i) $estimated_hours_work_min - set estimated_hours_max_arr($i) $estimated_hours_work_max - set end_date_arr($i) $end_date - set percent_complete_arr($i) $percent_complete - set actual_hours_worked_arr($i) $actual_hours_worked + set task_title_arr($i) $my_task_title + set description_arr($i) $my_description + set estimated_hours_arr($i) $my_estimated_work + set estimated_hours_min_arr($i) $my_estimated_work_min + set estimated_hours_max_arr($i) $my_estimated_work_max + set end_date_arr($i) $my_end_date + set percent_complete_arr($i) $my_percent_complete + set actual_hours_worked_arr($i) $my_actual_hours_worked set task_item_id_arr($i) [lindex $task_id [expr $i - 1]] + set dependency_arr($i) $my_dependency # we are not using a process set process_task_id_arr($i) "" @@ -281,6 +330,19 @@ ] ] + # -------------------------------------- + # we don't skip tasks when we're editing + # -------------------------------------- + ad_form -extend \ + -name add_edit \ + -form \ + [list [list \ + skip_task_p.$i:text(hidden) \ + {value {f}} \ + ] \ + ] + + incr i } } else { @@ -304,6 +366,7 @@ set actual_hours_worked_arr($i) 0 set task_item_id_arr($i) "" set process_task_id_arr($i) "" + set dependency_arr($i) "" if {[exists_and_not_null process_id]} { @@ -315,11 +378,43 @@ set estimated_hours_min_arr($i) $estimated_hours_work_min_v($ptask_id) set estimated_hours_max_arr($i) $estimated_hours_work_max_v($ptask_id) + # keeps track of what process_task_id this was based on # so we can later get info on what assignments the process # task had, and what dependencies as well set process_task_id_arr($i) $ptask_id + + # We also want to make it optional for the user whether or + # not they use any given task when they are using a + # process. Often, they will want to skips some of the + # tasks, and this gives them that option + + ad_form -extend \ + -name add_edit \ + -form \ + [list [list \ + skip_task_p.$i:text(select) \ + {label \"Skip this task?\"} \ + {options {{No f} {Yes t}}} \ + {value {f}} \ + {help_text {If you skip this task, it will not be created}} \ + ] \ + ] + + } else { + + # we never skip when there is no process being used + + ad_form -extend \ + -name add_edit \ + -form \ + [list [list \ + skip_task_p.$i:text(hidden) \ + {value {f}} \ + ] \ + ] + } # ----------------------------------------------------- @@ -379,18 +474,89 @@ # ---------------------------------------------------------------- # set up the tasks that can be viewed. Take out the current task. - # TODO: add in process defaults + + # --------------------------------------------------- + # set up the tasks that this task can be dependent on + # For new tasks, that includes the other new tasks + # We have to check later that the user doesn't enter + # any loops! + # --------------------------------------------------- + set dependency_options_full "" append dependency_options_full "{\"--None--\" \"\"} " - # adds in the NEW tasks as options. We have to check later to make sure - # the user doesn't enter any loops! - for {set j 1} {$j <= $number} {incr j} { - if {![string equal $i $j]} { - append dependency_options_full "{\"New Task \#$j\" \"num$j\"} " + + if {[string equal $edit_p f]} { + + # if we have a process, we need to bring in the dependencies + # from the process. + # + # We have the following: + # process_tasks: a list of all the process task ids, which act + # as keys for the other information. + # dependency_v(process_task_id) which process these tasks rely on. + # + + if {[exists_and_not_null process_id]} { + + # what is the task that the process says this task + # depends on? + set process_index [expr $i - 1] + + if {[exists_and_not_null dependency_v([lindex $process_tasks $process_index])]} { + set process_depend $dependency_v([lindex $process_tasks $process_index]) + } else { + set process_depend "XXX" + } + + # ns_log Notice "proces_depend $process_depend" + + # lsearch gives us the index value inside the + # process_tasks list. That corresponds to the task minus + # one. So we add one to this index, as long as the value + # is not -1 (which indicates that process_depend is not in + # the process_tasks list) + # ns_log Notice "lsearch [lsearch $process_tasks $process_depend]" + set which_dep_task [lsearch $process_tasks $process_depend] + + # ns_log Notice "process_tasks: $process_tasks" + + if {$which_dep_task >= 0} { + incr which_dep_task + } + + # ns_log Notice "which_dep_task $which_dep_task $i" + if {$which_dep_task == $process_index} { + set dependency_arr($i) "num$which_dep_task" + # ns_log Notice "num$which_dep_task" + } + } + + # now set up dependency options + + for {set j 1} {$j <= $number} {incr j} { + if {![string equal $i $j]} { + append dependency_options_full "{\"New Task \#$j\" \"num$j\"} " + } + } + } - foreach key $dependency_keys { - append dependency_options_full "{\"$key\" $dependency_options($key)} " + # for editing tasks, we skip ourselves (because depending on + # ourselves just sometimes isn't an option) + + if {[string equal $edit_p t]} { + foreach key $dependency_keys { + + # make sure we're not dependent on ourselves + + if {![string equal $task_item_id_arr($i) $dependency_options($key)]} { + append dependency_options_full "{\"$key\" $dependency_options($key)} " + } + } + } else { + foreach key $dependency_keys { + append dependency_options_full "{\"$key\" $dependency_options($key)} " + } } ad_form -extend \ @@ -434,6 +600,7 @@ dependency_task_id.$i:text(select),optional \ {label \"Dependency\"} \ {options {$dependency_options_full}} \ + {value {$dependency_arr($i)}} \ {help_text {$task_term the dependency is based on}} \ ] \ ] @@ -513,110 +680,91 @@ set p_work_min $estimated_hours_work_min($i) set p_work_max $estimated_hours_work_max($i) set p_dep_type $dependency_type($i) - set p_dep_id $dependency_task_id($i) - set parent_task_id $p_dep_id + set p_parent_task_id $dependency_task_id($i) + set p_skip_p $skip_task_p($i) - ns_log Notice "adding task: pii: $project_item_id tt:$p_task_title d:$p_description ed: end_date($i) w:$p_work m:$p_work_min mx:$p_work_max dep_type:$p_dep_type dep_id:$p_dep_id" + # ns_log Notice "adding task: pii: $project_item_id tt:$p_task_title d:$p_description ed: end_date($i) w:$p_work m:$p_work_min mx:$p_work_max dep_type:$p_dep_type parent:$p_parent_task_id" # add in the new task - set this_revision_id [project_manager::task::new \ - -project_id $project_item_id \ - -title $p_task_title \ - -description $p_description \ - -end_date [project_manager::project::util::datenvl -value [set end_date_$i] -value_if_null "" -value_if_not_null "to_timestamp('[set end_date_$i]','YYYY MM DD HH24 MI SS')"] \ - -percent_complete "0" \ - -estimated_hours_work $p_work \ - -estimated_hours_work_min $p_work_min \ - -estimated_hours_work_max $p_work_max \ - -creation_user $user_id \ - -creation_ip $peeraddr \ - -package_id $package_id - ] - set this_task_id [db_string get_task_item_id {}] - set dep_task_id($i) $this_task_id + if {[string equal $p_skip_p "f"]} { + set this_revision_id [pm::task::new \ + -project_id $project_item_id \ + -title $p_task_title \ + -description $p_description \ + -end_date [pm::project::util::datenvl -value [set end_date_$i] -value_if_null "" -value_if_not_null "to_timestamp('[set end_date_$i]','YYYY MM DD HH24 MI SS')"] \ + -percent_complete "0" \ + -estimated_hours_work $p_work \ + -estimated_hours_work_min $p_work_min \ + -estimated_hours_work_max $p_work_max \ + -creation_user $user_id \ + -creation_ip $peeraddr \ + -package_id $package_id + ] + + set this_task_id [db_string get_task_item_id {}] + + + + set dependent_task_id($i) $this_task_id - if {[exists_and_not_null p_dep_id]} { - - # if the p_dep_id contains num at the beginning, then - # the task is supposed to depend on other tasks that - # are currently being created. We have to do all sorts of - # things like make sure there are no loops, etc.. - if {[regexp {num.*} $p_dep_id]} { - regexp {num(.*)} $p_dep_id match d_parent - - # dep_parent tracks who is parent of what - set dep_parent($i) $d_parent - set dep_type($i) $p_dep_type - lappend parent_new_task $i - # we wait until after all the tasks have been created to create these - # dependencies - } else { - - # add in the new dependency - set dependency_id [db_nextval pm_task_dependency_seq] - db_dml new_dependency { *SQL* } + if {[exists_and_not_null p_parent_task_id]} { + + # if the p_parent_task_id contains num at the beginning, then + # the task is supposed to depend on other tasks that + # are currently being created. We have to wait until + # the tasks have been created + if {[regexp {num.*} $p_parent_task_id]} { + regexp {num(.*)} $p_parent_task_id match d_parent + + # dep_parent tracks who is parent of what + set dep_parent($i) $d_parent + set dep_type($i) $p_dep_type + lappend parent_new_task $i + # we wait until after all the tasks have been created to create these + # dependencies + } else { + + # add in the new dependency + pm::task::dependency_add \ + -task_item_id $this_task_id \ + -parent_id $parent_task_id \ + -dependency_type $p_dep_type \ + -project_item_id $project_item_id + } } - } - lappend process_task_id $process_task_ids($i) - lappend revisions $this_revision_id - lappend task_id $this_task_id + lappend process_task_id $process_task_ids($i) + lappend revisions $this_revision_id + lappend task_id $this_task_id + } } if {[exists_and_not_null parent_new_task]} { # there are tasks that depend on newly created tasks. # 1. check for loops # 2. if no loops, create dependencies - # the way we check for a loop is to follow the dependencies - # until we get to a task that has already been created. - # we make the assumption that the following is true: - # starting condition: no tasks are created - # when adding a task: no loop is created if you depend on a task already present - # therefore, if you add a task without creating a loop in the newly - # created tasks, you are safe. - - # we check that the new items don't depend on each other by following them - # if they loop more than $number times, then we have a loop - set loop_limit $number - foreach dep_task $parent_new_task { - set passes_p f - - set my_task $dep_task - while {$loop_limit >= 0} { - - if {[exists_and_not_null dep_parent($my_task)]} { - set my_task $dep_parent($my_task) - } else { - set passes_p t - break - } - - set loop_limit [expr $loop_limit - 1] - } - - if {[string equal $passes_p t]} { - # add in the new dependency - set dependency_id [db_nextval pm_task_dependency_seq] - set this_task_id $dep_task_id($dep_task) - set parent_task_id $dep_task_id($dep_parent($dep_task)) + set this_task_id $dependent_task_id($dep_task) + if {[info exists dependent_task_id($dep_parent($dep_task))]} { + set parent_task_id $dependent_task_id($dep_parent($dep_task)) set p_dep_type $dep_type($dep_task) - db_dml new_dependency { *SQL* } - } else { - ns_log Notice "PM: Adding in dependency failed for $dep_task_id($dep_task) due to looping" + + pm::task::dependency_add \ + -task_item_id $this_task_id \ + -parent_id $parent_task_id \ + -dependency_type $p_dep_type \ + -project_item_id $project_item_id } } - - } ns_log Notice "Project_item_id $project_item_id" - project_manager::project::compute_parent_status $project_item_id + pm::project::compute_parent_status $project_item_id } -edit_data { @@ -644,6 +792,7 @@ set end_date_$i "{} {} {} {} {} {}" } + # set up variables, pulling from arrays set p_task_item_id $task_item_id($i) set p_task_title $task_title($i) @@ -653,22 +802,53 @@ set p_work_min $estimated_hours_work_min($i) set p_work_max $estimated_hours_work_max($i) set p_hours $actual_hours_worked($i) + set p_parent_task_id $dependency_task_id($i) # do the actual edit - set this_revision_id [db_exec_plsql new_task_revision { }] + set this_revision_id [pm::task::update \ + -task_item_id $p_task_item_id \ + -project_item_id $project_item_id \ + -title $p_task_title \ + -description $p_description \ + -end_date "[set end_date_[set i]]" \ + -percent_complete $p_percent \ + -estimated_hours_work $p_work \ + -estimated_hours_work_min $p_work_min \ + -estimated_hours_work_max $p_work_max \ + -actual_hours_worked $p_hours \ + -update_user $user_id \ + -update_ip $peeraddr \ + -package_id $package_id] + - ns_log Notice "Added in $this_revision_id" + # set this_revision_id [db_exec_plsql new_task_revision { }] + # ns_log Notice "Added in $this_revision_id" + lappend revisions $this_revision_id - ns_log Notice "in new: task_id $task_id" + # ns_log Notice "in new: task_id $task_id" # BUG: we need to make sure we take care of deleting dependencies # if unchecked, adding dependencies, etc.. + pm::task::dependency_delete_all \ + -task_item_id $p_task_item_id + + ns_log Notice "p_parent_task_id $p_parent_task_id" + + if {![empty_string_p $p_parent_task_id]} { + + pm::task::dependency_add \ + -task_item_id $p_task_item_id \ + -parent_id $p_parent_task_id \ + -dependency_type fdsafeafes \ + -project_item_id $project_item_id + } + } - project_manager::project::compute_parent_status $project_item_id + pm::project::compute_parent_status $project_item_id ns_log Notice "computed parent pre redirect" Index: openacs-4/contrib/packages/project-manager/www/task-assign-add-edit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/task-assign-add-edit.adp,v diff -u -r1.4 -r1.4.2.1 --- openacs-4/contrib/packages/project-manager/www/task-assign-add-edit.adp 10 Nov 2003 19:34:54 -0000 1.4 +++ openacs-4/contrib/packages/project-manager/www/task-assign-add-edit.adp 27 Feb 2004 22:46:13 -0000 1.4.2.1 @@ -1,40 +1,49 @@ -@context_bar;noquote@ -@title@ + @context_bar;noquote@ + @title@ + +
-
+ - + - + + + + -
@tasks.one_line@
- - - + - - + - + + + + -
@tasks.one_line@
@tasks.description@ + + + + + - - - -
-
-
+
+
+ + -
+ -

+ + +

- + + + + +

- - -
- Index: openacs-4/contrib/packages/project-manager/www/task-assign-add-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/task-assign-add-edit.tcl,v diff -u -r1.5.2.6 -r1.5.2.7 --- openacs-4/contrib/packages/project-manager/www/task-assign-add-edit.tcl 5 Feb 2004 23:57:49 -0000 1.5.2.6 +++ openacs-4/contrib/packages/project-manager/www/task-assign-add-edit.tcl 27 Feb 2004 22:46:13 -0000 1.5.2.7 @@ -251,12 +251,12 @@ ----------- $descriptions($t_id)" - notification::request::new \ - -type_id [notification::type::get_type_id -short_name pm_task_notif] \ - -object_id $t_id \ - -user_id $p_id \ - -interval_id [notification::interval::get_id_from_name -name instant] \ - -delivery_method_id [notification::delivery::get_id -short_name email] + #notification::request::new \ + # -type_id "[notification::type::get_type_id -short_name pm_task_notif]" \ + # -object_id $t_id \ + # -user_id $p_id \ + # -interval_id [notification::interval::get_id_from_name -name instant] \ + # -delivery_method_id [notification::delivery::get_id -short_name email] notification::new \ -type_id [notification::type::get_type_id -short_name pm_task_notif] \ Index: openacs-4/contrib/packages/project-manager/www/tasks.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/contrib/packages/project-manager/www/Attic/tasks.tcl,v diff -u -r1.1.2.7 -r1.1.2.8 --- openacs-4/contrib/packages/project-manager/www/tasks.tcl 6 Feb 2004 17:20:43 -0000 1.1.2.7 +++ openacs-4/contrib/packages/project-manager/www/tasks.tcl 27 Feb 2004 22:46:13 -0000 1.1.2.8 @@ -48,7 +48,7 @@ # status defaults to open if {![exists_and_not_null status_id]} { - set status_id [project_manager::task::default_status_open] + set status_id [pm::task::default_status_open] } # permissions