Index: openacs-4/packages/logger/logger.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/logger.info,v diff -u -N -r1.10 -r1.11 --- openacs-4/packages/logger/logger.info 3 May 2004 18:04:44 -0000 1.10 +++ openacs-4/packages/logger/logger.info 3 Jun 2004 21:08:17 -0000 1.11 @@ -7,21 +7,23 @@ f f - + Lars Pind Peter Marklund Time and expenses reporting. - 2004-05-03 + 2004-05-26 Collaboraid - Logger lets you keep track of measurements over time. The primary use case is time and expenses reporting, an area where we are being guided by the HR-XML Time Expense Reporting 2.0 standard. However, the intention is to allow for reporting of arbitrary types of numerical data such as financial results - account balance, revenue etc. You could even use this application to monitor your weight. The full specification is here: <a href="http://www.collaboraid.biz/developer/logger-spec">http://www.collaboraid.biz/developer/logger-spec<a> - 0 + Logger lets you keep track of measurements over time. The primary use case is time and expenses reporting, an area where we are being guided by the HR-XML Time Expense Reporting 2.0 standard. However, the intention is to allow for reporting of arbitrary types of numerical data such as financial results - account balance, revenue etc. You could even use this application to monitor your weight. The full specification is here: <a href="http://www.collaboraid.biz/developer/logger-spec">http://www.collaboraid.biz/developer/logger-spec<a> + +Logger can be optionally integrated with project-manager, for logging of time against projects and tasks. - + + - + Index: openacs-4/packages/logger/lib/entries-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/lib/entries-oracle.xql,v diff -u -N -r1.1 -r1.2 --- openacs-4/packages/logger/lib/entries-oracle.xql 4 Jan 2004 21:27:48 -0000 1.1 +++ openacs-4/packages/logger/lib/entries-oracle.xql 3 Jun 2004 21:08:23 -0000 1.2 @@ -29,4 +29,32 @@ + + + select le.entry_id, + le.time_stamp, + to_char(le.time_stamp, 'YYYY-MM-DD HH24:MI:SS') as time_stamp_ansi, + to_char(le.time_stamp, 'IW-YYYY') as time_stamp_week, + le.value, + le.description, + lp.project_id, + lp.name as project_name, + submitter.person_id as user_id, + submitter.first_names || ' ' || submitter.last_name as user_name, + c.category_id, + c.tree_id + from logger_entries le + LEFT OUTER JOIN + category_object_map_tree c on (c.object_id = le.entry_id), + logger_projects lp, + acs_objects ao, + persons submitter + where le.project_id = lp.project_id + and ao.object_id = le.entry_id + and ao.creation_user = submitter.person_id + [list::filter_where_clauses -and -name "entries"] + [list::orderby_clause -orderby -name "entries"] + + + Index: openacs-4/packages/logger/lib/entries-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/lib/entries-postgresql.xql,v diff -u -N -r1.1 -r1.2 --- openacs-4/packages/logger/lib/entries-postgresql.xql 4 Jan 2004 21:27:48 -0000 1.1 +++ openacs-4/packages/logger/lib/entries-postgresql.xql 3 Jun 2004 21:08:23 -0000 1.2 @@ -5,28 +5,61 @@ - select le.entry_id, - acs_permission__permission_p(le.entry_id, :current_user_id, 'delete') as delete_p, - acs_permission__permission_p(le.entry_id, :current_user_id, 'write') as edit_p, - le.time_stamp, - to_char(le.time_stamp, 'fmDyfm fmMMfm-fmDDfm-YYYY') as time_stamp_pretty, - to_char(le.time_stamp, 'IW-YYYY') as time_stamp_week, - le.value, - le.description, + select le.entry_id, + acs_permission__permission_p(le.entry_id, :current_user_id, 'delete') as delete_p, + acs_permission__permission_p(le.entry_id, :current_user_id, 'write') as edit_p, + le.time_stamp, + to_char(le.time_stamp, 'fmDyfm fmMMfm-fmDDfm-YYYY') as time_stamp_pretty, + to_char(le.time_stamp, 'IW-YYYY') as time_stamp_week, + le.value, + le.description, + $task_select lp.project_id, - lp.name as project_name, - submitter.user_id, - submitter.first_names || ' ' || submitter.last_name as user_name - from logger_entries le, - logger_projects lp, - acs_objects ao, - cc_users submitter - where le.project_id = lp.project_id - and ao.object_id = le.entry_id - and ao.creation_user = submitter.user_id + lp.name as project_name, + submitter.person_id as user_id, + submitter.first_names || ' ' || submitter.last_name as user_name + from logger_entries le + $task_left_join + logger_projects lp, + acs_objects ao, + persons submitter + where le.project_id = lp.project_id + and ao.object_id = le.entry_id + and ao.creation_user = submitter.person_id [list::filter_where_clauses -and -name "entries"] - [list::orderby_clause -orderby -name "entries"] + [list::orderby_clause -orderby -name "entries"] + + + select le.entry_id, + le.time_stamp, + to_char(le.time_stamp, 'YYYY-MM-DD HH24:MI:SS') as time_stamp_ansi, + to_char(le.time_stamp, 'IW-YYYY') as time_stamp_week, + le.value, + le.description, + lp.project_id, + lp.name as project_name, + $task_select + submitter.person_id as user_id, + submitter.first_names || ' ' || submitter.last_name as user_name, + c.category_id, + c.tree_id + from logger_entries le + LEFT OUTER JOIN + category_object_map_tree c + ON (c.object_id = le.entry_id) + $task_left_join + logger_projects lp, + acs_objects ao, + persons submitter + where le.project_id = lp.project_id + and ao.object_id = le.entry_id + and ao.creation_user = submitter.person_id + [list::filter_where_clauses -and -name "entries"] + [list::orderby_clause -orderby -name "entries"] + + + Index: openacs-4/packages/logger/lib/entries.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/lib/entries.tcl,v diff -u -N -r1.10 -r1.11 --- openacs-4/packages/logger/lib/entries.tcl 16 Feb 2004 15:08:29 -0000 1.10 +++ openacs-4/packages/logger/lib/entries.tcl 3 Jun 2004 21:08:23 -0000 1.11 @@ -1,16 +1,71 @@ # Expected variables: -# +# ------------------- # filters_p, default true, show filters -# if { ![exists_and_not_null filters_p] } { set filters_p 1 } +# Optional variables: +# ------------------- +# pm_task_id +# pm_project_id +# show_tasks_p +# show_orderby_p the calling include may not want to show links to sort +# project_id +# variable_id +# start_date in ansi format +# end_date in ansi format +# format (normal is default) +# url : of logger (if called by another package) /url/to/logger/ +# add_link If you want to override the add link (for example, to go +# directly to the correct project) +# project_manager_url : if passed in, the /url/to/project-manager/ +# that is used to display the link to the task and project page. +# entry_id (not sure if this works), should highlight entries. +# return_url (used for delete links) + if { ![exists_and_not_null format] } { set format "normal" } +if { ![exists_and_not_null show_tasks_p]} { + set show_tasks_p 0 +} + +if { ![info exists project_manager_url]} { + set project_manager_url "" +} + +# Debugging: +# ns_log notice "project: $project_id variable_id: $variable_id filters_p: $filters_p pm_project_id: $pm_project_id pm_task_id: $pm_task_id start_date:$start_date end_date: $end_date show_orderby: $show_orderby_p entry_id: $entry_id show_tasks_p: $show_tasks_p" + + +# Usage: +# ------ +# This can be used as an include for the main index page of logger, +# and it can be also used in includes from other apps, like +# project-manager. The most important distinction is whether or not +# filter options are going to be shown. If they are, then a lot more +# computation has to be done. + +# Because this can be called from other packages as well, the URLs we +# compute have to be fully qualified. + +if {[info exists url]} { + set base_url $url +} else { + set base_url [ad_conn package_url] +} + +# Testing: +# -------- +# use cases to test for: +# using logger with and without project-manager +# when using project-manager, both integrated and not integrated with PM +# using logger with categories and without + + set package_id [ad_conn package_id] set current_user_id [ad_conn user_id] set admin_p [permission::permission_p -object_id $package_id -privilege admin] @@ -27,14 +82,30 @@ set weekdayno [clock format [clock seconds] -format %w] set monthdayno [string trimleft [clock format [clock seconds] -format %d] 0] +# ----------------------- +# PREPARATION FOR FILTERS +# ----------------------- + # 1. get category-trees mapped to projects in this logger -set project_ids [logger::package::all_projects_in_package -package_id [ad_conn package_id]] + +# the logger::package::all_projects_in_package proc may be able to be +# optimized in some way? If you have thousands of projects, it tends +# to be a bit slow. Perhaps limit the results to only open projects? + +if {[exists_and_not_null project_id] && !$filters_p} { + set project_ids [list $project_id] +} else { + set project_ids [logger::package::all_projects_in_package -package_id [ad_conn package_id]] +} + array set tree_id_array [list] -foreach id $project_ids { - foreach elm [category_tree::get_mapped_trees $id] { - set tree_id_array([lindex $elm 0]) . - } + +set elm_forest [category_tree::get_mapped_trees_from_object_list $project_ids] + +foreach elm $elm_forest { + set tree_id_array([lindex $elm 0]) . } + set tree_ids [array names tree_id_array] @@ -49,6 +120,15 @@ } # Projects + +# we don't need to show all the project options if this is being +# displayed in an include, and we're not showing the filters. +if {$filters_p} { + set project_where "" +} else { + set project_where "and lp.project_id = :project_id" +} + set project_values [db_list_of_lists select_projects {}] if { ([exists_and_not_null start_date] || [exists_and_not_null end_date]) && ![exists_and_not_null time_stamp] } { @@ -91,7 +171,7 @@ } value { label $variable(name) - link_url_eval {log?[export_vars { entry_id }]} + link_url_eval {[export_vars -base "${my_base_url}log" { entry_id }]} link_html { title "View this entry" } aggregate {[ad_decode $variable(type) "additive" sum average]} html { align right } @@ -100,14 +180,18 @@ description { label "Description" display_eval {[string_truncate -len 50 -- $description]} - link_url_eval {log?[export_vars { entry_id }]} + link_url_eval {[export_vars -base "${my_base_url}log" { entry_id }]} link_html { title "View this entry" } } + task_name { + label "Task" + link_url_eval {[export_vars -base "${my_project_manager_url}task-one" { task_id }]} +} description_long { label "Description" display_eval {[string_truncate -len 400 -- $description]} hide_p 1 - link_url_eval {log?[export_vars { entry_id }]} + link_url_eval {[export_vars -base "${my_base_url}log" { entry_id }]} link_html { title "View this entry" } } } @@ -123,7 +207,7 @@ where_clause { le.project_id = :project_id } - add_url_eval {[export_vars -base "log" { { project_id $__filter_value } variable_id }]} + add_url_eval {[export_vars -base "${base_url}log" { { project_id $__filter_value } variable_id }]} has_default_p {[ad_decode [llength $project_values] 1 1 0]} } variable_id { @@ -132,7 +216,7 @@ where_clause { le.variable_id = :variable_id } - add_url_eval {[ad_decode [exists_and_not_null project_id] 1 [export_vars -base "log" { project_id { variable_id $__filter_value } }] ""]} + add_url_eval {[ad_decode [exists_and_not_null project_id] 1 [export_vars -base "${base_url}log" { project_id { variable_id $__filter_value } }] ""]} has_default_p t } projection_id { @@ -145,7 +229,7 @@ label "Users" values {[db_list_of_lists select_users {}]} where_clause { - submitter.user_id = :user_id + submitter.person_id = :user_id } } time_stamp { @@ -213,6 +297,12 @@ } } } + pm_task_id { + label "Tasks" + where_clause { + task.item_id = :pm_task_id + } + } } set orderbys { @@ -245,6 +335,12 @@ default_value time_stamp,desc } +# the calling include may not want to show links to sort +if {[exists_and_not_null show_orderby_p] && !$show_orderby_p} { + set orderbys "" +} + + set groupby_values { { "Day" { { groupby time_stamp } { orderby time_stamp,desc } } } { "Week" { { groupby time_stamp_week } { orderby time_stamp,desc } } } @@ -297,13 +393,53 @@ [list orderby c_${id}_category_id]]] } + +if {$show_tasks_p} { + lappend normal_row task_name {} +} + lappend normal_row value {} description {} + +# we modify the queries if we are viewing tasks + +if { $show_tasks_p || [exists_and_not_null pm_task_id]} { + set task_select "case when task.title is null then '' else task.title end as task_name, task.item_id as task_id," + + set task_left_join { + LEFT JOIN (select + r.title, + m.logger_entry, + i.item_id + from + cr_items i, + cr_revisions r, + pm_task_logger_proj_map m + where + r.item_id = m.task_item_id and + i.live_revision = r.revision_id) task + ON le.entry_id = task.logger_entry, + } +} else { + set task_left_join "," + set task_select "" +} + #---------------------------------------------------------------------- # Define list #---------------------------------------------------------------------- +if {![info exists add_link]} { + set add_link "${base_url}project-select" +} + +set actions_list [list "Add Entry" $add_link "Add new log entry"] + +set delete_link "${base_url}log-delete" + +set bulk_actions_list [list "Delete" $delete_link "Delete checked entries"] + list::create \ -name entries \ -multirow entries \ @@ -316,11 +452,12 @@ -sub_class "narrow" \ -pass_properties { variable - } -actions { - "Add Entry" "project-select" "Add new log entry" - } -bulk_actions { - "Delete" "log-delete" "Delete checked entries" - } -elements $elements -filters $filters \ + } -actions $actions_list \ + -bulk_actions $bulk_actions_list \ + -bulk_action_export_vars { + return_url + } \ + -elements $elements -filters $filters \ -groupby { label "Group by" type multivar @@ -389,38 +526,21 @@ # We add a virtual column per category tree -set extend { edit_url delete_url delete_onclick time_stamp_pretty edit_p delete_p } +# some more documentation of what's going on here would be helpful. + +set extend { edit_url delete_url delete_onclick time_stamp_pretty edit_p delete_p my_base_url my_project_manager_url } foreach id $tree_ids { lappend extend c_${id}_category_id } array set row_categories [list] array set project_write_p [list] -db_multirow -extend $extend -unclobber entries select_entries2 " - select le.entry_id, - le.time_stamp, - to_char(le.time_stamp, 'YYYY-MM-DD HH24:MI:SS') as time_stamp_ansi, - to_char(le.time_stamp, 'IW-YYYY') as time_stamp_week, - le.value, - le.description, - lp.project_id, - lp.name as project_name, - submitter.user_id, - submitter.first_names || ' ' || submitter.last_name as user_name, - c.category_id, - c.tree_id - from logger_entries le left outer join - category_object_map_tree c on (c.object_id = le.entry_id), - logger_projects lp, - acs_objects ao, - cc_users submitter - where le.project_id = lp.project_id - and ao.object_id = le.entry_id - and ao.creation_user = submitter.user_id - [list::filter_where_clauses -and -name "entries"] - [list::orderby_clause -orderby -name "entries"] -" { +db_multirow -extend $extend -unclobber entries select_entries2 { } { + + set my_base_url $base_url + set my_project_manager_url $project_manager_url + if { ![empty_string_p $tree_id] && ![empty_string_p $category_id] } { lappend row_categories($tree_id) $category_id } @@ -429,15 +549,15 @@ continue } else { set selected_p [string equal [ns_queryget entry_id] $entry_id] - set edit_url [export_vars -base log { entry_id { edit t } { return_url [ad_return_url] } }] + set edit_url [export_vars -base "${base_url}log" { entry_id { edit t } { return_url [ad_return_url] } }] if { ![exists_and_not_null project_write_p($project_id)] } { set project_write_p($project_id) [template::util::is_true [permission::permission_p -object_id $project_id -privilege write]] } set edit_p [expr $project_write_p($project_id) || ($user_id == [ad_conn user_id])] set delete_p $edit_p if { $delete_p } { set delete_onclick "return confirm('Are you sure you want to delete log entry with $value $variable(unit) $variable(name) on $time_stamp?');" - set delete_url [export_vars -base log-delete { entry_id }] + set delete_url [export_vars -base "${base_url}log-delete" { entry_id }] } else { set delete_url {} } Index: openacs-4/packages/logger/lib/entries.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/lib/entries.xql,v diff -u -N -r1.4 -r1.5 --- openacs-4/packages/logger/lib/entries.xql 27 Feb 2004 17:43:50 -0000 1.4 +++ openacs-4/packages/logger/lib/entries.xql 3 Jun 2004 21:08:23 -0000 1.5 @@ -27,7 +27,8 @@ logger_project_pkg_map lppm where lp.project_id = lppm.project_id and lppm.package_id = :package_id - and lp.active_p = 't' + and lp.active_p = 't' + $project_where order by lp.name @@ -48,17 +49,17 @@ select submitter.first_names || ' ' || submitter.last_name as label, - submitter.user_id as user_id - from cc_users submitter, + submitter.person_id as user_id + from persons submitter, logger_entries le, acs_objects ao where ao.object_id = le.entry_id - and submitter.user_id = ao.creation_user + and submitter.person_id = ao.creation_user and exists (select 1 from logger_project_pkg_map where project_id = le.project_id and package_id = :package_id) - group by submitter.user_id, submitter.first_names, submitter.last_name + group by submitter.person_id, submitter.first_names, submitter.last_name Index: openacs-4/packages/logger/lib/nav-bar.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/lib/nav-bar.adp,v diff -u -N -r1.1 -r1.2 --- openacs-4/packages/logger/lib/nav-bar.adp 5 Jan 2004 20:23:50 -0000 1.1 +++ openacs-4/packages/logger/lib/nav-bar.adp 3 Jun 2004 21:08:23 -0000 1.2 @@ -7,7 +7,9 @@  |  - @links.name@ + + @links.name@ +    Index: openacs-4/packages/logger/lib/nav-bar.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/lib/nav-bar.tcl,v diff -u -N -r1.1 -r1.2 --- openacs-4/packages/logger/lib/nav-bar.tcl 5 Jan 2004 20:23:50 -0000 1.1 +++ openacs-4/packages/logger/lib/nav-bar.tcl 3 Jun 2004 21:08:23 -0000 1.2 @@ -5,6 +5,8 @@ set package_url [ad_conn package_url] set page_url [ad_conn url] +set project_manager_url [logger::util::project_manager_url] + set admin_p [permission::permission_p -object_id $package_id -privilege admin] # The links used in the navbar on format url1 label1 url2 label2 ... @@ -16,7 +18,7 @@ lappend link_list {} lappend link_list "List" -# My log entrie page +# My log entry page if { [ad_conn user_id] != 0 } { lappend link_list $index_urls lappend link_list [list [list user_id $user_id]] @@ -25,6 +27,21 @@ lappend link_list [list "${package_url}project-select"] lappend link_list {} lappend link_list "Add Entry" + + if {![empty_string_p $project_manager_url]} { + lappend link_list [list "${project_manager_url}"] + lappend link_list {} + lappend link_list "Projects" + + lappend link_list [list "${project_manager_url}processes"] + lappend link_list {} + lappend link_list "Processes" + + lappend link_list [list "${project_manager_url}tasks"] + lappend link_list {} + lappend link_list "Tasks" + + } } # The admin index page Index: openacs-4/packages/logger/tcl/entry-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/tcl/entry-procs-postgresql.xql,v diff -u -N -r1.1 -r1.2 --- openacs-4/packages/logger/tcl/entry-procs-postgresql.xql 8 May 2003 13:54:59 -0000 1.1 +++ openacs-4/packages/logger/tcl/entry-procs-postgresql.xql 3 Jun 2004 21:08:24 -0000 1.2 @@ -24,4 +24,15 @@ + + + SELECT + task_item_id + FROM + pm_task_logger_proj_map m + WHERE + logger_entry = :entry_id + + + Index: openacs-4/packages/logger/tcl/entry-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/tcl/entry-procs.tcl,v diff -u -N -r1.4 -r1.5 --- openacs-4/packages/logger/tcl/entry-procs.tcl 27 Mar 2004 01:08:20 -0000 1.4 +++ openacs-4/packages/logger/tcl/entry-procs.tcl 3 Jun 2004 21:08:24 -0000 1.5 @@ -17,6 +17,9 @@ {-time_stamp:required} {-description ""} {-party_id ""} + {-task_item_id ""} + {-project_item_id ""} + {-update_status_p:boolean} } {

Create a logger entry. @@ -37,6 +40,16 @@ @param party_id The party that is entering the logged entry. Defaults to ad_conn user_id if nothing is passed in + @param task_item_id If passed in, the project-manager task + to log time against + + @param project_item_id If passed in, the project-manager project + + @param update_status_p If set, updates the project manager project + status, using pm::project::compute_status + + @see pm::project::compute_status + @return The entry_id of the created project. @author Peter Marklund @@ -52,27 +65,108 @@ # The creator can admin his own entry permission::grant -party_id $creation_user -object_id $entry_id -privilege admin + # if we have a task_id, then we need to note that this + # entry is logged to a particular task. + if {[exists_and_not_null task_item_id]} { + db_dml delete_logger_map { + DELETE FROM + pm_task_logger_proj_map + WHERE + logger_entry = :entry_id + } + + db_dml add_logger_map " + INSERT INTO + pm_task_logger_proj_map + (task_item_id, + logger_entry) + VALUES + (:task_item_id, + :entry_id) + " + + pm::task::update_hours \ + -task_item_id $task_item_id \ + -update_tasks_p t + + if { $update_status_p } { + pm::project::compute_status $project_item_id + } + } + + return $entry_id } ad_proc -public logger::entry::edit { {-entry_id:required} {-value:required} {-time_stamp:required} - {-description ""} + {-description ""} + {-task_item_id ""} + {-project_item_id ""} + {-update_status:boolean} } { Edit a entry. @param entry_id The id of the entry to edit @param value The new value of the entry @param time_stamp The new time stamp of the entry @param description The new description of the entry + @param task_item_id If passed in, the project-manager task + to log time against + @param project_item_id If passed in, the project-manager project + + @param update_status If set, updates the project manager project + status, using pm::project::compute_status + + @see pm::project::compute_status + @return The return value from db_dml @author Peter Marklund } { db_dml update_entry {} + + # all ignored if project-manager isn't installed and linked + + if {[logger::util::project_manager_linked_p]} { + + # delete any linked in tasks (an entry could be linked to a + # task, and the user could decide to log against the project only) + db_dml delete_logger_map { + DELETE FROM + pm_task_logger_proj_map + WHERE + logger_entry = :entry_id + } + + # if we have a task_id, then we need to note that this + # entry is logged to a particular task. + if {[exists_and_not_null task_item_id]} { + + db_dml add_logger_map " + INSERT INTO + pm_task_logger_proj_map + (task_item_id, + logger_entry) + VALUES + (:task_item_id, + :entry_id) + " + + pm::task::update_hours \ + -task_item_id $task_item_id \ + -update_tasks_p t + + } + + if { $update_status_p } { + pm::project::compute_status $project_item_id + } + + } } ad_proc -public logger::entry::delete { @@ -110,3 +204,23 @@ db_1row select_entry {} -column_array entry_array } + + +ad_proc -public logger::entry::task_id { + -entry_id:required +} { + Returns the task_id corresponding to an entry if one exists + + This should only be called if project manager is installed. + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-05-28 + + @param entry_id + + @return empty string if no task corresponds to this entry + + @error +} { + return [db_string task_id { } -default ""] +} Index: openacs-4/packages/logger/tcl/entry-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/tcl/entry-procs.xql,v diff -u -N -r1.2 -r1.3 --- openacs-4/packages/logger/tcl/entry-procs.xql 1 May 2003 10:00:24 -0000 1.2 +++ openacs-4/packages/logger/tcl/entry-procs.xql 3 Jun 2004 21:08:24 -0000 1.3 @@ -29,4 +29,10 @@ + + + select current_timestamp when 1 = 0 + + + Index: openacs-4/packages/logger/tcl/package-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/tcl/package-procs.tcl,v diff -u -N -r1.6 -r1.7 --- openacs-4/packages/logger/tcl/package-procs.tcl 11 Jan 2004 17:52:40 -0000 1.6 +++ openacs-4/packages/logger/tcl/package-procs.tcl 3 Jun 2004 21:08:24 -0000 1.7 @@ -75,3 +75,65 @@ db_multirow variables select_variables {} } + + +ad_proc -public logger::package::map_project { + -project_id:required + {-package_id ""} +} { + Maps a project to a package + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-05-20 + + @param project_id + + @param package_id A package ID (must be present in the + apm_packages table) + + @return + + @error +} { + + if {[empty_string_p $package_id]} { + set package_id [ad_conn package_id] + } + + permission::require_permission -object_id $project_id -privilege "read" + + db_dml map_project { + insert into logger_project_pkg_map (project_id, package_id) values (:project_id, :package_id) + } + + return 1 +} + + +ad_proc -public logger::package::unmap_project { + -project_id:required + -package_id:required +} { + Unmaps a project from a package + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-05-20 + + @param project_id + + @param package_id + + @return + + @error +} { + + db_dml map_project { + delete + from logger_project_pkg_map + where project_id = :project_id + and package_id = :package_id + } + + return 1 +} Index: openacs-4/packages/logger/tcl/project-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/tcl/project-procs.tcl,v diff -u -N -r1.9 -r1.10 --- openacs-4/packages/logger/tcl/project-procs.tcl 27 Feb 2004 17:43:51 -0000 1.9 +++ openacs-4/packages/logger/tcl/project-procs.tcl 3 Jun 2004 21:08:24 -0000 1.10 @@ -299,3 +299,71 @@ } { return [db_string select_current_projection {} -default {}] } + +ad_proc -public logger::project::remap_variables { + -project_id:required + -new_variable_list:required +} { + When given a list of variable IDs, sets the variables to be + equal to the new variable list. + + Note this proc does not honor the default variables very much, + and will remap them. Feel free to improve this if it affects + you. + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-05-20 + + @param project_id the logger project ID + + @param new_variable_list a list of variable IDs + + @return + + @error +} { + + set current_variables_list [logger::project::get_variables -project_id $project_id] + + set primary_variable [logger::project::get_primary_variable -project_id $project_id] + set default_variable [logger::variable::get_default_variable_id] + + foreach new_id $new_variable_list { + + # we only add it if it isn't already there + if {[lsearch $current_variables_list $new_id] < 0} { + logger::project::map_variable \ + -project_id $project_id \ + -variable_id $new_id + } + } + + # if one of the new variables is the default variable, set it + # as the default variable for *that project* + if {[lsearch $new_variable_list $default_variable] >= 0} { + + logger::project::set_primary_variable \ + -project_id $project_id \ + -variable_id $default_variable + + } else { + + logger::project::set_primary_variable \ + -project_id $project_id \ + -variable_id "[lindex $new_variable_list 0]" + } + + foreach old_id $current_variables_list { + + # we only remove it if it isn't in the new list + if {[lsearch $new_variable_list $old_id] < 0} { + + logger::project::unmap_variable \ + -project_id $project_id \ + -variable_id $old_id + } + + } + + return 1 +} Index: openacs-4/packages/logger/tcl/ui-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/tcl/ui-procs.tcl,v diff -u -N -r1.8 -r1.9 --- openacs-4/packages/logger/tcl/ui-procs.tcl 28 Aug 2003 09:45:30 -0000 1.8 +++ openacs-4/packages/logger/tcl/ui-procs.tcl 3 Jun 2004 21:08:24 -0000 1.9 @@ -90,6 +90,20 @@ return [db_list_of_lists variable_options {}] } +ad_proc -public logger::ui::variable_options_all { +} { + Return a list suitable to be passed to the form builder + for the select box of all variables that could be mapped to a project. + + @return A list with variable options on the format + [list [list variable_label1 variable_id1] [list variable_label2 variable_value2] ...] + + @author Jade Rubick +} { + + return [db_list_of_lists variable_options_all {}] +} + ad_proc -public logger::ui::project_options {} { Return a list suitable to be passed to the form builder for the select box of the projects mapped to the @@ -103,3 +117,54 @@ set package_id [ad_conn package_id] return [db_list_of_lists project_options {}] } + + +ad_proc -public logger::ui::variable_select_widget { + -project_id:required + {-current_variable_id ""} + -select_name:required +} { + Returns a select widget, suitable for use in a form, that + contains all the current variables in use for a project + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-05-21 + + @param project_id + + @param current_variable_id Optionally, the currently selected + variable. If left blank, will be set to the default variable_id + for that project + + @param select_name What the name of the select widget should be + + @return An HTML chunk suitable for display in a form. + + @error +} { + + if {[empty_string_p $current_variable_id]} { + set current_variable_id [logger::project::get_primary_variable \ + -project_id $project_id] + } + + set variable_options [logger::ui::variable_options \ + -project_id $project_id] + + + set variable_widget "" + + return $variable_widget +} Index: openacs-4/packages/logger/tcl/ui-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/tcl/ui-procs.xql,v diff -u -N -r1.4 -r1.5 --- openacs-4/packages/logger/tcl/ui-procs.xql 27 Feb 2004 17:43:51 -0000 1.4 +++ openacs-4/packages/logger/tcl/ui-procs.xql 3 Jun 2004 21:08:24 -0000 1.5 @@ -13,6 +13,18 @@ + + + SELECT + lv.name || ' (in ' || lv.unit || ')', + lv.variable_id + FROM + logger_variables lv + ORDER BY + lv.name, lv.unit + + + select lp.name, Index: openacs-4/packages/logger/tcl/util-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/tcl/util-procs.tcl,v diff -u -N -r1.3 -r1.4 --- openacs-4/packages/logger/tcl/util-procs.tcl 23 Sep 2003 08:36:33 -0000 1.3 +++ openacs-4/packages/logger/tcl/util-procs.tcl 3 Jun 2004 21:08:24 -0000 1.4 @@ -60,3 +60,99 @@ return $ad_conn_name } + + +ad_proc -public logger::util::project_manager_url { +} { + Returns a valid URL to a project-manager instance, if and only if this + logger instance is set up to be integrated in project-manager. + This is set in the project-manager admin pages. Currently, this + proc assumes it is called from within logger. + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-05-24 + + @return empty string if there is no linked in project-manager + + @error +} { + + set package_id [ad_conn package_id] + + return [util_memoize "logger::util::project_manager_url_cached -package_id $package_id"] + +} + + +ad_proc -private logger::util::project_manager_url_cached { + -package_id:required +} { + Memoized portion of project_manager_url + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-05-24 + + @see logger::util::project_manager_url + + @return + + @error empty string if project manager is not installed +} { + + set package_url [ad_conn package_url] + + # assumes that these return in the same order! + set possible_packages [site_node::get_children -all -package_key project-manager -node_id [site_node::get_node_id -url "/"] -element package_id] + set possible_urls [site_node::get_children -all -package_key project-manager -node_id [site_node::get_node_id -url "/"]] + + set return_url "" + + # we go through the list of project-manager URLs, and check if the + # current package_url is listed as one to be integrated with + # project-manager. If it is, we return the URL to that + # project-manager instance. + + set index 0 + + foreach this_package_id $possible_packages { + + set primary_url [parameter::get \ + -package_id $this_package_id \ + -parameter "LoggerPrimaryURL"] + + if {![empty_string_p $primary_url]} { + + if {[string equal $package_url $primary_url]} { + + set project_manager_url [lindex $possible_urls $index] + + set return_url $project_manager_url + } + } + + incr index + } + + return $return_url +} + + +ad_proc -public logger::util::project_manager_linked_p { +} { + Returns 1 if there is a project manager linked to this instance + + @author Jade Rubick (jader@bread.com) + @creation-date 2004-06-03 + + @return + + @error +} { + set url [logger::util::project_manager_url] + + if {[empty_string_p $url]} { + return 0 + } else { + return 1 + } +} Index: openacs-4/packages/logger/tcl/variable-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/tcl/variable-procs-postgresql.xql,v diff -u -N -r1.3 -r1.4 --- openacs-4/packages/logger/tcl/variable-procs-postgresql.xql 29 Sep 2003 10:21:52 -0000 1.3 +++ openacs-4/packages/logger/tcl/variable-procs-postgresql.xql 3 Jun 2004 21:08:24 -0000 1.4 @@ -23,6 +23,22 @@ + + + select vm.variable_id + from logger_project_var_map vm, + logger_project_pkg_map pm, + logger_projects p + where vm.primary_p = 't' + and vm.project_id = pm.project_id + and pm.package_id = :package_id + and p.project_id = pm.project_id + and p.active_p = 't' + order by lower(p.name) + limit 1 + + + select variable_id Index: openacs-4/packages/logger/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/index.adp,v diff -u -N -r1.16 -r1.17 --- openacs-4/packages/logger/www/index.adp 27 Feb 2004 16:58:13 -0000 1.16 +++ openacs-4/packages/logger/www/index.adp 3 Jun 2004 21:08:24 -0000 1.17 @@ -12,7 +12,8 @@ - + + &="page" + &="return_url" + &="project_manager_url" + &="show_tasks_p"> + + + + Index: openacs-4/packages/logger/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/index.tcl,v diff -u -N -r1.22 -r1.23 --- openacs-4/packages/logger/www/index.tcl 27 Feb 2004 17:43:52 -0000 1.22 +++ openacs-4/packages/logger/www/index.tcl 3 Jun 2004 21:08:24 -0000 1.23 @@ -41,6 +41,8 @@ set instance_name [ad_conn instance_name] +set return_url [ad_return_url] + set admin_p [permission::permission_p -object_id [ad_conn package_id] -privilege admin] if { ![exists_and_not_null project_id] } { @@ -60,3 +62,30 @@ -project_id $project_id \ -variable_id $variable_id] } + + +# get the project_manager_url if this is related to project manager +set project_manager_url [logger::util::project_manager_url] + +if {![empty_string_p $project_manager_url]} { + set show_tasks_p 1 + + # project manager is installed, so we set the corresponding project + if {[exists_and_not_null project_id]} { + set pm_project_id [pm::project::get_project -logger_project $project_id] + } else { + set pm_project_id "" + } + + # we only call this if project_manager is installed (the url is + # not empty) + if { [exists_and_not_null entry_id]} { + set pm_task_id [logger::entry::task_id -entry_id $entry_id] + } else { + set pm_task_id "" + } + +} else { + set show_tasks_p 0 +} + Index: openacs-4/packages/logger/www/log-delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/log-delete.tcl,v diff -u -N -r1.5 -r1.6 --- openacs-4/packages/logger/www/log-delete.tcl 11 Mar 2004 10:24:21 -0000 1.5 +++ openacs-4/packages/logger/www/log-delete.tcl 3 Jun 2004 21:08:24 -0000 1.6 @@ -31,5 +31,8 @@ logger::entry::delete -entry_id $entry_id } -ad_returnredirect $return_url +ad_returnredirect -message "Entry deleted" $return_url + +# should update project-manager if appropriate + ad_script_abort Index: openacs-4/packages/logger/www/log.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/log.adp,v diff -u -N -r1.14 -r1.15 --- openacs-4/packages/logger/www/log.adp 17 May 2004 15:15:20 -0000 1.14 +++ openacs-4/packages/logger/www/log.adp 3 Jun 2004 21:08:24 -0000 1.15 @@ -49,12 +49,16 @@

Recent Entries

+ show_tasks_p="@show_tasks_p;noquote@" + return_url="@return_url;noquote@" + project_manager_url="@project_manager_url;noquote@" + /> Index: openacs-4/packages/logger/www/log.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/log.tcl,v diff -u -N -r1.21 -r1.22 --- openacs-4/packages/logger/www/log.tcl 8 Mar 2004 20:31:22 -0000 1.21 +++ openacs-4/packages/logger/www/log.tcl 3 Jun 2004 21:08:24 -0000 1.22 @@ -2,6 +2,7 @@ Add/edit/display a log entry. @author Peter Marklund (peter@collaboraid.biz) + @author Jade Rubick (jader@bread.com) project-manager integration @creation-date 2003-04-16 @cvs-id $Id$ } { @@ -10,6 +11,9 @@ variable_id:integer,optional {edit:boolean "f"} {return_url "."} + {pm_project_id:integer ""} + {pm_task_id:integer ""} + {__refreshing_p "0"} } -validate { project_id_required_in_add_mode { # For the sake of simplicity of the form @@ -20,12 +24,13 @@ } } + # TODO: Make the recent entries list start on the date of the last entry set package_id [ad_conn package_id] set current_user_id [ad_maybe_redirect_for_registration] -if { [exists_and_not_null entry_id] } { +if { [exists_and_not_null entry_id] && [logger::util::project_manager_linked_p]} { set entry_exists_p [db_string entry_exists_p {}] } else { set entry_exists_p 0 @@ -74,6 +79,20 @@ logger::project::get -project_id $project_id -array project_array logger::variable::get -variable_id $variable_id -array variable_array +# get the project_manager_url if this is related to project manager +set project_manager_url [logger::util::project_manager_url] + +if {![empty_string_p $project_manager_url]} { + # project manager is installed, so we set the corresponding project + set pm_project_id [pm::project::get_project -logger_project $project_id] + + #we only call this if project_manager is installed (the url is + #not empty) + if { [exists_and_not_null entry_id] && [empty_string_p $pm_task_id]} { + set pm_task_id [logger::entry::task_id -entry_id $entry_id] + } +} + ########### # # Build the form @@ -90,14 +109,20 @@ # Different page title and form mode when adding a log entry # versus displaying/editing one -if { [exists_and_not_null entry_id] } { +if { [exists_and_not_null entry_id] || ${__refreshing_p} } { # Initial request in display or edit mode or a submit of the form set page_title "Edit Log Entry" + if { [string equal $edit "t"] && $edit_p } { set ad_form_mode edit } else { set ad_form_mode display } + + if { ${__refreshing_p} } { + set ad_form_mode edit + } + } else { # Initial request in add mode set page_title "Add Log Entry" @@ -125,6 +150,7 @@ ad_form -extend -name log_entry_form -export { project_id variable_id return_url } -form { {project:text(inform) + {section "Project"} {label Project} {value $project_array(name)} } @@ -148,14 +174,26 @@ -form_name log_entry_form +# we want to give the option of choosing task if you have chosen a +# project. When a new task is chosen, we want to change the +# information shown about that task + +if {[logger::util::project_manager_linked_p]} { + + set task_options [list] + + set task_options [pm::task::options_list \ + -project_item_id $pm_project_id] +} + # Add form elements common to all modes # The form builder date datatype doesn't take ANSI format date strings # but wants dates in list format ad_form -extend -name log_entry_form -form { {value:float {label $variable_array(name)} {after_html $variable_array(unit)} - {html {size 9 maxlength 9}} + {html {size 7 maxlength 7}} } {description:text,optional {label Description} @@ -166,6 +204,93 @@ } } +# Additions to form if project-manager is involved. +if {[exists_and_not_null pm_task_id]} { + + # do I really need this both here and in the -on_refresh block? -jr + + db_1row get_task_values " + SELECT + title as task_title, + case when percent_complete is null then 0 + else percent_complete end as percent_complete, + estimated_hours_work, + estimated_hours_work_min, + estimated_hours_work_max, + s.description as status_description + FROM + pm_tasks_revisionsx p, + cr_items i, + pm_task_status s, + pm_tasks t + WHERE i.item_id = p.item_id and + p.item_id = :pm_task_id and + i.item_id = t.task_id and + t.status = s.status_id and + p.revision_id = i.live_revision" + + ad_form -extend -name log_entry_form -form { + + {pm_project_id:text(hidden) + {value $pm_project_id} + } + {pm_task_id:integer(select),optional + {section "Task"} + {label "Subject"} + {options {$task_options}} + {html {onChange "document.log_entry_form.__refreshing_p.value='1';submit()"}} + {value $pm_task_id} + {help} + {help_text "If you change this, please wait for the page to refresh"} + } + {status_description:text(inform) + {label "Status"} + } + } + + set display_hours [pm::task::estimated_hours_work \ + -estimated_hours_work "$estimated_hours_work" \ + -estimated_hours_work_min "$estimated_hours_work_min" \ + -estimated_hours_work_max "$estimated_hours_work_max" \ + ] + + ad_form -extend -name log_entry_form -form { + + {estimated_hours_work:text(inform) + {label "Estimated work"} + {value $display_hours} + {after_html "hours"} + } + } + + ad_form -extend -name log_entry_form -form { + + {percent_complete:float + {label "Complete"} + {value $percent_complete} + {after_html "%"} + {html {size 5 maxlength 5}} + {help} + {help_text "Set to 100% to close the task, less to open it"} + } + + } + +} + + +# set the headers so you can get back to project manager. + +if { [exists_and_not_null pm_task_id] } { + + set context [list [list "${project_manager_url}task-one?task_id=$pm_task_id" "$task_title"] $page_title] + +} elseif { [exists_and_not_null pm_project_id] } { + + set context [list [list "${project_manager_url}one?project_item_id=$pm_project_id" "$project_array(name)"] $page_title] + +} + ########### # # Execute the form @@ -203,13 +328,35 @@ -variable_id $variable_id \ -value $value \ -time_stamp $time_stamp \ - -description $description + -description $description \ + -task_item_id $pm_task_id \ + -project_item_id $pm_project_id + + if {[exists_and_not_null pm_task_id]} { + + pm::task::update_percent \ + -task_item_id $pm_task_id \ + -percent_complete $percent_complete + + } + } else { logger::entry::edit \ -entry_id $entry_id \ -value $value \ -time_stamp $time_stamp \ - -description $description + -description "$description" \ + -task_item_id "$pm_task_id" \ + -project_item_id "$pm_project_id" + + if {[exists_and_not_null pm_task_id]} { + + pm::task::update_percent \ + -task_item_id "$pm_task_id" \ + -percent_complete "$percent_complete" + + } + } category::map_object \ @@ -223,16 +370,27 @@ ad_set_client_property logger time_stamp $time_stamp # Present the user with an add form again for quick logging - ad_returnredirect -message "Log entry for $value $variable_array(unit) with description \"$description\" added." [export_vars -base [ad_conn url] { project_id variable_id }] + ad_returnredirect -message "Log entry for $value $variable_array(unit) with description \"$description\" added." [export_vars -base [ad_conn url] { project_id variable_id pm_project_id pm_task_id}] ad_script_abort } -edit_data { db_transaction { - logger::entry::edit \ - -entry_id $entry_id \ - -value $value \ - -time_stamp $time_stamp \ - -description $description + + if {[info exists pm_task_id] && [info exists pm_project_id]} { + logger::entry::edit \ + -entry_id $entry_id \ + -value $value \ + -time_stamp $time_stamp \ + -description $description \ + -task_item_id "$pm_task_id" \ + -project_item_id "$pm_project_id" + } else { + logger::entry::edit \ + -entry_id $entry_id \ + -value $value \ + -time_stamp $time_stamp \ + -description $description + } category::map_object \ -remove_old \ @@ -241,18 +399,82 @@ -container_object_id $the_project_id] } + if {[logger::util::project_manager_linked_p]} { + set this_task_id [db_string task_entry_p "select task_item_id from pm_task_logger_proj_map where logger_entry = :entry_id" -default "-1"] + } else { + set this_task_id -1 + } + + if {![string equal $this_task_id -1] && [exists_and_not_null percent_complete]} { + + pm::task::update_percent \ + -task_item_id "$this_task_id" \ + -percent_complete "$percent_complete" + + pm::task::update_hours \ + -task_item_id $this_task_id \ + -update_tasks_p t + + } + } -after_submit { ad_returnredirect -message "Log entry modified." $return_url + + if {![string equal $pm_task_id -1]} { + pm::project::compute_status $pm_project_id + } + ad_script_abort +} -on_refresh { + + db_1row get_task_values " + SELECT + title as task_title, + case when percent_complete is null then 0 + else percent_complete end as percent_complete, + estimated_hours_work, + estimated_hours_work_min, + estimated_hours_work_max, + s.description as status_description + FROM + pm_tasks_revisionsx p, + cr_items i, + pm_task_status s, + pm_tasks t + WHERE i.item_id = p.item_id and + p.item_id = :pm_task_id and + i.item_id = t.task_id and + t.status = s.status_id and + p.revision_id = i.live_revision" + + foreach element [list percent_complete status_description] { + template::element set_value log_entry_form $element [set $element] + } + + set display_hours [pm::task::estimated_hours_work \ + -estimated_hours_work "$estimated_hours_work" \ + -estimated_hours_work_min "$estimated_hours_work_min" \ + -estimated_hours_work_max "$estimated_hours_work_max"] + + template::element set_value log_entry_form estimated_hours_work $display_hours + } + ########### # # Log history # ########### +# only show tasks is project-manager is installed +if {[logger::util::project_manager_linked_p]} { + set show_tasks_p t +} else { + set show_tasks_p f +} + # Show the log history if the user is looking at /editing his own entry or if # the user is adding a new entry if { $entry_exists_p && [string equal $current_user_id $entry_array(creation_user)] } { @@ -299,8 +521,12 @@ -format $ansi_format_string] } -set add_entry_url [export_vars -base log { project_id variable_id }] +set add_entry_url [export_vars -base log { project_id variable_id pm_project_id pm_task_id}] +# because we're using /lib/entries, this is not implemented right +# now. The /lib/entries section should be updated to highlight the +# current entry_id. + if { [info exists entry_id] } { set entry_id_or_blank $entry_id } else { @@ -315,9 +541,7 @@ ##### db_multirow -extend { url selected_p } variables select_variables {} { - set url [export_vars -base log -override { {variable_id $unique_id} } { project_id }] + set url [export_vars -base log -override { {variable_id $unique_id} } { project_id pm_project_id pm_task_id }] set selected_p [string equal $variable_id $unique_id] } - - Index: openacs-4/packages/logger/www/admin/project-instance-map.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/admin/project-instance-map.tcl,v diff -u -N -r1.1 -r1.2 --- openacs-4/packages/logger/www/admin/project-instance-map.tcl 8 May 2003 13:56:04 -0000 1.1 +++ openacs-4/packages/logger/www/admin/project-instance-map.tcl 3 Jun 2004 21:08:24 -0000 1.2 @@ -9,18 +9,16 @@ if { [string equal $unmap "f"] } { - permission::require_permission -object_id $project_id -privilege "read" - - db_dml map_project { - insert into logger_project_pkg_map (project_id, package_id) values (:project_id, :package_id) - } + logger::package::map_project \ + -project_id $project_id \ + -package_id $package_id + } else { - db_dml map_project { - delete - from logger_project_pkg_map - where project_id = :project_id - and package_id = :package_id - } + + logger::package::unmap_project \ + -project_id $project_id \ + -package_id $package_id + } ad_returnredirect .