Index: openacs-4/packages/logger/logger.info
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/logger/logger.info,v
diff -u -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 @@
     <initial-install-p>f</initial-install-p>
     <singleton-p>f</singleton-p>
     
-    <version name="1.0b4" url="http://openacs.org/repository/download/apm/logger-1.0b4.apm">
+    <version name="1.0b5" url="http://openacs.org/repository/download/apm/logger-1.0b5.apm">
         <owner url="mailto:lars@collaboraid.biz">Lars Pind</owner>
         <owner url="mailto:peter@collaboraid.biz">Peter Marklund</owner>
         <summary>Time and expenses reporting.</summary>
-        <release-date>2004-05-03</release-date>
+        <release-date>2004-05-26</release-date>
         <vendor url="http://www.collaboraid.biz">Collaboraid</vendor>
-        <description format="text/html">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: &lt;a href=&quot;http://www.collaboraid.biz/developer/logger-spec&quot;&gt;http://www.collaboraid.biz/developer/logger-spec&lt;a&gt;</description>
-        <maturity>0</maturity>
+        <description format="text/html">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: &lt;a href=&quot;http://www.collaboraid.biz/developer/logger-spec&quot;&gt;http://www.collaboraid.biz/developer/logger-spec&lt;a&gt;
+
+Logger can be optionally integrated with project-manager, for logging of time against projects and tasks.</description>
 
-        <provides url="logger" version="1.0b4"/>
+        <provides url="logger" version="1.0b5"/>
         <requires url="acs-tcl" version="4.6.2"/>
+        <requires url="categories" version="1.0d3"/>
 
         <callbacks>
-            <callback type="before-uninstall"  proc="logger::apm::before_uninstall"/>
             <callback type="after-install"  proc="logger::apm::after_install"/>
+            <callback type="before-uninstall"  proc="logger::apm::before_uninstall"/>
             <callback type="before-uninstantiate"  proc="logger::apm::before_uninstantiate"/>
         </callbacks>
         <parameters>
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 -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 @@
     </querytext>
   </fullquery>
 
+  <fullquery name="select_entries2">
+    <querytext>
+    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"]
+    </querytext>
+  </fullquery>
+
 </queryset>
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 -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 @@
 
   <fullquery name="select_entries">
     <querytext>
-	    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"]
     </querytext>
   </fullquery>
 
+  <fullquery name="select_entries2">
+    <querytext>
+    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"]
+    </querytext>
+  </fullquery>
+
 </queryset>
Index: openacs-4/packages/logger/lib/entries.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/logger/lib/entries.tcl,v
diff -u -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 -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
     </querytext>
   </fullquery>
@@ -48,17 +49,17 @@
   <fullquery name="select_users">
     <querytext>
     	    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
     </querytext>
   </fullquery>
 
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 -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 @@
             <td class="logger_navbar">
               <multiple name="links">
                 <if @links.rownum@ gt 1>&nbsp;|&nbsp;</if>
-                <a href="@links.url@" class="logger_navbar">@links.name@</a>
+              <if @links.selected_p@><i></if>
+              <a href="@links.url@" class="logger_navbar">@links.name@</a>
+              <if @links.selected_p@></i></if>
               </multiple>
               &nbsp;&nbsp;
             </td>
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 -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 -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 @@
     </querytext>
   </fullquery>
  
+  <fullquery name="logger::entry::task_id.task_id">
+    <querytext>
+      SELECT
+      task_item_id
+      FROM
+      pm_task_logger_proj_map m
+      WHERE
+      logger_entry = :entry_id
+    </querytext>
+  </fullquery>
+
 </queryset>
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 -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}
 } {
     <p>
       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 -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 @@
     </querytext>
   </fullquery>
 
+  <fullquery name="logger::entry::task_id.task_id">
+    <querytext>
+      select current_timestamp when 1 = 0
+    </querytext>
+  </fullquery>
+
 </queryset>
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 -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 -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 -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 "<select name=\"$select_name\">"
+    foreach option $variable_options {
+
+        set name [lindex $option 0]
+        set id   [lindex $option 1]
+        
+        if {[string equal $id $current_variable_id]} {
+            append variable_widget "<option selected value=\"$id\">$name</option>"
+        } else {
+            append variable_widget "<option value=\"$id\">$name</option>"
+        }
+    }
+    append variable_widget "</select>"
+
+    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 -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 @@
     </querytext>
   </fullquery>
 
+  <fullquery name="logger::ui::variable_options_all.variable_options_all">
+    <querytext>
+      SELECT 
+      lv.name || ' (in ' || lv.unit || ')',
+      lv.variable_id
+      FROM 
+      logger_variables lv
+      ORDER BY
+      lv.name, lv.unit
+    </querytext>
+  </fullquery>
+
   <fullquery name="logger::ui::project_options.project_options">
     <querytext>
         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 -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 -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 @@
     </querytext>
   </fullquery>
  
+  <fullquery name="logger::variable::get_default_variable_id.select_first_project_primary_variable">
+    <querytext>
+            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
+    </querytext>
+  </fullquery>
+
   <fullquery name="logger::variable::get_default_variable_id.select_first_variable_id">
     <querytext>
         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 -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 @@
   </if>
 </if>
 <else>
-  <include src="/packages/logger/lib/entries" 
+  <if @show_tasks_p@ eq 1>
+      <include src="/packages/logger/lib/entries" 
       &="entry_id"
       &="variable_id"
       &="project_id"
@@ -24,5 +25,26 @@
       &="groupby"
       &="orderby"
       &="format"
-      &="page">
+      &="page"
+      &="return_url"
+      &="project_manager_url"
+      &="show_tasks_p">
+  </if>
+  <else>
+      <include src="/packages/logger/lib/entries" 
+      &="entry_id"
+      &="variable_id"
+      &="project_id"
+      &="user_id"
+      &="time_stamp"
+      &="start_date"
+      &="end_date"
+      &="projection_id"
+      &="groupby"
+      &="orderby"
+      &="format"
+      &="page"
+      &="return_url"
+      &="show_tasks_p">
+  </else>
 </else>
Index: openacs-4/packages/logger/www/index.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/index.tcl,v
diff -u -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 -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 -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 @@
   <h3 class="logger" style="clear: left;">Recent Entries</h3>
 
   <include src="/packages/logger/lib/entries" 
-      user_id="@current_user_id;noquote@" 
       project_id="@project_id;noquote@" 
       variable_id="@variable_id;noquote@" 
+      filters_p="f"
+      pm_project_id="@pm_project_id;noquote@" 
       start_date="@start_date_ansi;noquote@"
       end_date="@end_date_ansi;noquote@"
+      show_orderby_p="f"
       entry_id="@entry_id_or_blank;noquote@"
-      filters_p="f"
-  />
+      show_tasks_p="@show_tasks_p;noquote@"
+      return_url="@return_url;noquote@"
+      project_manager_url="@project_manager_url;noquote@"
+      /> 
 </if>
Index: openacs-4/packages/logger/www/log.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/log.tcl,v
diff -u -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 -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 .