Index: openacs-4/packages/logger/www/index.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/index.adp,v
diff -u -r1.8.4.1 -r1.8.4.2
--- openacs-4/packages/logger/www/index.adp	13 May 2003 14:56:49 -0000	1.8.4.1
+++ openacs-4/packages/logger/www/index.adp	15 May 2003 08:48:52 -0000	1.8.4.2
@@ -69,7 +69,8 @@
                                        projection_value="@selected_projection_value@" 
                                        selected_user_id="@selected_user_id@" 
                                        start_date_ansi="@selected_start_date@" 
-                                       end_date_ansi="@selected_end_date@"/>
+                                       end_date_ansi="@selected_end_date@"
+                                       group_by="@selected_group_by@" />
 
       <!-- End log entries body -->
     </td>
Index: openacs-4/packages/logger/www/index.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/index.tcl,v
diff -u -r1.10.4.2 -r1.10.4.3
--- openacs-4/packages/logger/www/index.tcl	14 May 2003 17:57:59 -0000	1.10.4.2
+++ openacs-4/packages/logger/www/index.tcl	15 May 2003 08:48:52 -0000	1.10.4.3
@@ -11,8 +11,17 @@
     {selected_user_id:integer ""}
     {selected_start_date ""}
     {selected_end_date ""}
+    {selected_group_by ""}
 }
 
+if { [empty_string_p [ad_conn query]] } {
+    set weekdayno [clock format [clock seconds] -format %w]
+    set new_start_date [clock format [clock scan "-$weekdayno days"] -format "%Y-%m-%d"]
+    set new_end_date [clock format [clock scan "[expr 6-$weekdayno] days"] -format "%Y-%m-%d"]
+    ad_returnredirect ".?[export_vars { { selected_start_date $new_start_date } { selected_end_date $new_end_date } { selected_group_by "time_stamp" } }]"
+    ad_script_abort
+}
+
 set package_id [ad_conn package_id]
 set current_user_id [ad_conn user_id]
 set instance_name [ad_conn instance_name]
@@ -25,6 +34,7 @@
     selected_user_id
     selected_start_date
     selected_end_date
+    selected_group_by
 }
 
 
@@ -137,7 +147,7 @@
         }
     }
     # Redirect so we get the dates in pretty mode
-    ad_returnredirect ".?[export_vars $filter_var_list]"
+    ad_returnredirect ".?[export_vars -no_empty $filter_var_list]"
     ad_script_abort
 }
 
@@ -151,7 +161,7 @@
 ###########
 
 if { [exists_and_not_null selected_project_id] } {
-    set all_projects_url ".?[export_vars -exclude { selected_project_id } $filter_var_list]"
+    set all_projects_url ".?[export_vars -no_empty -exclude { selected_project_id } $filter_var_list]"
 } else {
     set all_projects_url {}
 }
@@ -162,8 +172,8 @@
 db_multirow -extend { filter_name url entry_add_url selected_p clear_url start_date end_date } filters select_projects {} {
     set filter_name "Projects"
 
-    set url ".?[export_vars -override { { selected_project_id $unique_id } } $filter_var_list]"
-    set entry_add_url "log?[export_vars { { project_id $unique_id } {variable_id $selected_variable_id}}]"
+    set url ".?[export_vars -no_empty -override { { selected_project_id $unique_id } } $filter_var_list]"
+    set entry_add_url "log?[export_vars -no_empty { { project_id $unique_id } {variable_id $selected_variable_id}}]"
     set selected_p [string equal $selected_project_id $unique_id]
     set name [string_truncate -len 25 $name]
     set clear_url $all_projects_url
@@ -208,10 +218,10 @@
 
 db_multirow -append -extend { filter_name url entry_add_url selected_p clear_url start_date end_date } filters select_variables {} {
     set filter_name "Variables"
-    set url ".?[export_vars -override { {selected_variable_id $unique_id} } $filter_var_list]"
+    set url ".?[export_vars -no_empty -override { {selected_variable_id $unique_id} } $filter_var_list]"
     if { ![empty_string_p $selected_project_id] } {
         # A project is selected - enable logging
-        set entry_add_url "log?[export_vars { { variable_id $unique_id } {project_id $selected_project_id}}]"
+        set entry_add_url "log?[export_vars -no_empty { { variable_id $unique_id } {project_id $selected_project_id}}]"
     } else {
         # No project selected - we wont enable those url:s
         set entry_add_url ""
@@ -227,7 +237,7 @@
 ###########
 
 if { [exists_and_not_null selected_user_id] } {
-    set all_users_url ".?[export_vars -exclude { selected_user_id } $filter_var_list]"
+    set all_users_url ".?[export_vars -no_empty -exclude { selected_user_id } $filter_var_list]"
 } else {
     set all_users_url {}
 }
@@ -249,7 +259,7 @@
 
 db_multirow -append -extend { filter_name url entry_add_url selected_p clear_url start_date end_date } filters select_users {} {
     set filter_name "Users"
-    set url ".?[export_vars -override { {selected_user_id $unique_id} } $filter_var_list]"
+    set url ".?[export_vars -no_empty -override { {selected_user_id $unique_id} } $filter_var_list]"
     set entry_add_url {}
     set selected_p [string equal $selected_user_id $unique_id]
     set clear_url $all_users_url
@@ -265,15 +275,15 @@
 if { ![empty_string_p $selected_project_id] && ![empty_string_p $selected_variable_id] } {
 
     if { [exists_and_not_null selected_projection_id] } {
-        set clear_projections_url ".?[export_vars -exclude { selected_projection_id } $filter_var_list]"
+        set clear_projections_url ".?[export_vars -no_empty -exclude { selected_projection_id } $filter_var_list]"
     } else {
         set clear_projections_url {}
     }
 
     db_multirow -append -extend { filter_name url entry_add_url selected_p clear_url } filters select_projections {} {
         set filter_name "Projections"
         set name [string_truncate -len 25 $name]
-        set url ".?[export_vars -override { {selected_projection_id $unique_id} { selected_start_date $start_date } { selected_end_date $end_date } } $filter_var_list]"
+        set url ".?[export_vars -no_empty -override { {selected_projection_id $unique_id} { selected_start_date $start_date } { selected_end_date $end_date } } $filter_var_list]"
         set entry_add_url {}
         set selected_p [string equal $selected_projection_id $unique_id]
         set clear_url $clear_projections_url
@@ -288,7 +298,7 @@
 #####
 
 if { [exists_and_not_null selected_start_date] || [exists_and_not_null selected_end_date] } {
-    set date_clear_url ".?[export_vars -exclude { selected_start_date selected_end_date } $filter_var_list]"
+    set date_clear_url ".?[export_vars -no_empty -exclude { selected_start_date selected_end_date } $filter_var_list]"
 } else {
     set date_clear_url {}
 }
@@ -344,7 +354,7 @@
         }
     }
 
-    set url ".?[export_vars -override { { selected_start_date $new_start_date } { selected_end_date $new_end_date }} $filter_var_list]"
+    set url ".?[export_vars -no_empty -override { { selected_start_date $new_start_date } { selected_end_date $new_end_date }} $filter_var_list]"
 
     set selected_p [expr [string equal $selected_start_date $new_start_date] && [string equal $selected_end_date $new_end_date]]
 
@@ -357,5 +367,37 @@
 
 # Custom
 if { $custom_p } {
+    # unique_id name filter_name url entry_add_url selected_p clear_url
     multirow append filters "" "Custom range" $filter_name "" "" $custom_p $date_clear_url {} {}
 }
+
+#####
+#
+# Group by filter
+#
+#####
+
+# TODO:
+# Flag to export_vars -no_empty which doesn't export empty strings
+
+if { [exists_and_not_null selected_group_by] } {
+    set group_clear_url ".?[export_vars -no_empty -exclude { selected_group_by } $filter_var_list]"
+} else {
+    set group_clear_url {}
+}
+
+array set group_label {
+    time_stamp "Day"
+    time_stamp_week "Week"
+    project_name "Project"
+    user_id "User"
+}
+
+foreach unique_id { time_stamp_week time_stamp project_name user_id } {
+    set url ".?[export_vars -no_empty -override { { selected_group_by $unique_id } } $filter_var_list]"
+
+    set selected_p [string equal $selected_group_by $unique_id]
+
+    # unique_id name filter_name url entry_add_url selected_p clear_url
+    multirow append filters $unique_id $group_label($unique_id) "Group by" $url "" $selected_p $group_clear_url
+}
Index: openacs-4/packages/logger/www/lib/entries-table-oracle.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/lib/Attic/entries-table-oracle.xql,v
diff -u -r1.1.4.1 -r1.1.4.2
--- openacs-4/packages/logger/www/lib/entries-table-oracle.xql	13 May 2003 10:10:36 -0000	1.1.4.1
+++ openacs-4/packages/logger/www/lib/entries-table-oracle.xql	15 May 2003 08:49:36 -0000	1.1.4.2
@@ -9,7 +9,8 @@
 	           acs_permission.permission_p(le.entry_id, :current_user_id, 'delete') as delete_p,
 	           acs_permission.permission_p(le.entry_id, :current_user_id, 'edit') as edit_p,
 	           le.time_stamp,
-	           to_char(le.time_stamp, 'fmMMfm-fmDDfm-YYYY') as time_stamp_pretty,
+	           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,
 	           lp.name as project_name,
@@ -23,7 +24,7 @@
 	      and ao.object_id = le.entry_id
 	      and ao.creation_user = submitter.user_id
 	    [ad_decode $where_clauses "" "" "and [join $where_clauses "\n    and "]"]
-	    order by le.time_stamp desc, ao.creation_date desc
+	    order by $order_by
     </querytext>
   </fullquery>
 
Index: openacs-4/packages/logger/www/lib/entries-table-postgresql.xql
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/lib/Attic/entries-table-postgresql.xql,v
diff -u -r1.1.4.1 -r1.1.4.2
--- openacs-4/packages/logger/www/lib/entries-table-postgresql.xql	13 May 2003 10:10:36 -0000	1.1.4.1
+++ openacs-4/packages/logger/www/lib/entries-table-postgresql.xql	15 May 2003 08:49:36 -0000	1.1.4.2
@@ -9,7 +9,8 @@
 	           acs_permission__permission_p(le.entry_id, :current_user_id, 'delete') as delete_p,
 	           acs_permission__permission_p(le.entry_id, :current_user_id, 'edit') as edit_p,
 	           le.time_stamp,
-	           to_char(le.time_stamp, 'fmMMfm-fmDDfm-YYYY') as time_stamp_pretty,
+	           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,
 	           lp.name as project_name,
@@ -23,7 +24,7 @@
 	      and ao.object_id = le.entry_id
 	      and ao.creation_user = submitter.user_id
 	    [ad_decode $where_clauses "" "" "and [join $where_clauses "\n    and "]"]
-	    order by le.time_stamp desc, ao.creation_date desc
+	    order by $order_by
     </querytext>
   </fullquery>
 
Index: openacs-4/packages/logger/www/lib/entries-table.adp
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/lib/Attic/entries-table.adp,v
diff -u -r1.4.2.2 -r1.4.2.3
--- openacs-4/packages/logger/www/lib/entries-table.adp	13 May 2003 15:42:42 -0000	1.4.2.2
+++ openacs-4/packages/logger/www/lib/entries-table.adp	15 May 2003 08:49:36 -0000	1.4.2.3
@@ -14,46 +14,135 @@
       <th class="logger_listing_narrow">Description</th>
       <th class="logger_listing_narrow">&nbsp;</th>
     </tr>
-  <multiple name="entries">
-    <if @entries.selected_p@ true>
+
+    <if @group_by@ not nil>
+      <multiple name="entries">
+        <tr class="logger_listing_spacer">
+          <td colspan="7">
+            &nbsp;
+          </td>
+        </tr>
         <tr class="logger_listing_subheader">
+          <td colspan="7">
+            <switch @group_by@>
+              <case value="user_id">
+                User: @entries.user_chunk@
+              </case>
+              <case value="project_name">
+                Project: @entries.project_name@
+              </case>
+              <case value="time_stamp">
+                Date: @entries.time_stamp_pretty@
+              </case>
+              <case value="time_stamp_week">
+                Week: @entries.time_stamp_week@
+              </case>
+              <default>
+                Unknown group by column @group_by@
+              </default>
+            </switch>
+          </td>
+        </tr>
+        <group column="@group_by@">
+          <if @entries.selected_p@ true>
+              <tr class="logger_listing_subheader">
+          </if>
+          <else>
+            <if @entries.rownum@ odd>
+              <tr class="logger_listing_odd">
+            </if>
+            <else>
+              <tr class="logger_listing_even">
+            </else>
+          </else>
+            <td class="logger_listing_narrow">
+              <if @entries.edit_p@ or @current_user_id@ eq @entries.user_id@>
+                <a href="@entries.edit_url@" title="Edit this log entry"><img src="/shared/images/Edit16.gif" height="16" width="16" alt="Edit" border="0"></a>
+              </if>
+            </td>
+            <td class="logger_listing_narrow">@entries.project_name@</td>
+            <td class="logger_listing_narrow">@entries.user_chunk@</td>
+            <td class="logger_listing_narrow" align="left">@entries.time_stamp_pretty@</td>
+            <td class="logger_listing_narrow" align="right" nowrap>
+              <if @entries.edit_p@ or @current_user_id@ eq @entries.user_id@>
+                <a href="@entries.view_url@" title="View this log entry">@entries.value@</a>
+              </if>
+              <else>
+                <a href="@entries.view_url@" title="View this log entry">@entries.value@</a>
+              </else>
+            </td>
+            <td class="logger_listing_narrow">
+              <a href="@entries.view_url@" title="View this log entry">@entries.description@</a>
+            </td>
+            <td class="logger_listing_narrow">
+              <if @entries.delete_url@ not nil>
+                <a href="@entries.delete_url@" onclick="@entries.delete_onclick@" title="Delete this log entry"><img src="/shared/images/Delete16.gif" height="16" width="16" alt="Delete" border="0"></a>
+              </if>
+            </td>
+          </tr>
+          <if @entries.groupnum_last_p@ true>
+            <tr class="logger_listing_subheader">
+              <td class="logger_listing_narrow" align="center">&nbsp;</td>
+              <td class="logger_listing_narrow" colspan="3">
+                <b>Subtotal</b>
+              </td>
+              <td class="logger_listing_narrow" align="right" nowrap>
+                <b>@entries.subtotal@</b>
+              </td>
+              <td class="logger_listing_narrow">&nbsp;</td>
+              <td class="logger_listing_narrow" align="center">&nbsp;</td>
+            </tr>
+          </if>
+        </group>
+      </multiple>
     </if>
-    <else>
-      <if @entries.rownum@ odd>
-        <tr class="logger_listing_odd">
+  <else>
+    <multiple name="entries">
+      <if @entries.selected_p@ true>
+          <tr class="logger_listing_subheader">
       </if>
       <else>
-        <tr class="logger_listing_even">
-      </else>
-    </else>
-      <td class="logger_listing_narrow">
-        <if @entries.edit_p@ or @current_user_id@ eq @entries.user_id@>
-          <a href="@entries.edit_url@" title="Edit this log entry"><img src="/shared/images/Edit16.gif" height="16" width="16" alt="Edit" border="0"></a>
+        <if @entries.rownum@ odd>
+          <tr class="logger_listing_odd">
         </if>
-      </td>
-      <td class="logger_listing_narrow">@entries.project_name@</td>
-      <td class="logger_listing_narrow">@entries.user_chunk@</td>
-      <td class="logger_listing_narrow" align="left">@entries.time_stamp_pretty@</td>
-      <td class="logger_listing_narrow" align="right" nowrap>
-        <if @entries.edit_p@ or @current_user_id@ eq @entries.user_id@>
-          <a href="@entries.view_url@" title="View this log entry">@entries.value@</a>
-        </if>
         <else>
-          <a href="@entries.view_url@" title="View this log entry">@entries.value@</a>
+          <tr class="logger_listing_even">
         </else>
-      </td>
-      <td class="logger_listing_narrow">
-        <a href="@entries.view_url@" title="View this log entry">@entries.description@</a>
-      </td>
-      <td class="logger_listing_narrow">
-        <if @entries.delete_url@ not nil>
-          <a href="@entries.delete_url@" onclick="@entries.delete_onclick@" title="Delete this log entry"><img src="/shared/images/Delete16.gif" height="16" width="16" alt="Delete" border="0"></a>
-        </if>
-      </td>
-    </tr>
-  </multiple>
+      </else>
+        <td class="logger_listing_narrow">
+          <if @entries.edit_p@ or @current_user_id@ eq @entries.user_id@>
+            <a href="@entries.edit_url@" title="Edit this log entry"><img src="/shared/images/Edit16.gif" height="16" width="16" alt="Edit" border="0"></a>
+          </if>
+        </td>
+        <td class="logger_listing_narrow">@entries.project_name@</td>
+        <td class="logger_listing_narrow">@entries.user_chunk@</td>
+        <td class="logger_listing_narrow" align="left">@entries.time_stamp_pretty@</td>
+        <td class="logger_listing_narrow" align="right" nowrap>
+          <if @entries.edit_p@ or @current_user_id@ eq @entries.user_id@>
+            <a href="@entries.view_url@" title="View this log entry">@entries.value@</a>
+          </if>
+          <else>
+            <a href="@entries.view_url@" title="View this log entry">@entries.value@</a>
+          </else>
+        </td>
+        <td class="logger_listing_narrow">
+          <a href="@entries.view_url@" title="View this log entry">@entries.description@</a>
+        </td>
+        <td class="logger_listing_narrow">
+          <if @entries.delete_url@ not nil>
+            <a href="@entries.delete_url@" onclick="@entries.delete_onclick@" title="Delete this log entry"><img src="/shared/images/Delete16.gif" height="16" width="16" alt="Delete" border="0"></a>
+          </if>
+        </td>
+      </tr>
+    </multiple>
+  </else>
 
     <!-- Row for the grand total -->
+    <tr class="logger_listing_spacer">
+      <td colspan="7">
+        &nbsp;
+      </td>
+    </tr>
     <tr class="logger_listing_subheader">
       <td class="logger_listing_narrow" align="center">&nbsp;</td>
       <td class="logger_listing_narrow" colspan="3">
@@ -88,6 +177,11 @@
 
     <!-- Row for projected value -->
   <if @projection_value@ not nil>
+    <tr class="logger_listing_spacer">
+      <td colspan="7">
+        &nbsp;
+      </td>
+    </tr>
     <tr class="logger_listing_odd">
       <td class="logger_listing_narrow" align="center">&nbsp;</td>
       <td class="logger_listing_narrow" colspan="3"><b>Projection</b></td>
@@ -97,15 +191,16 @@
     </tr>
   </if>
 
-    <tr class="logger_listing_even">
-      <th class="logger_listing_narrow">&nbsp;</th>
-      <th class="logger_listing_narrow">&nbsp;</th>  
-      <th class="logger_listing_narrow">&nbsp;</th>  
-      <th class="logger_listing_narrow">&nbsp;</th>
-      <th class="logger_listing_narrow">@variable.unit@</th>
-      <th class="logger_listing_narrow">&nbsp;</th>
-      <th class="logger_listing_narrow">&nbsp;</th>
-    </tr>
+  <!-- Unit -->
+  <tr class="logger_listing_even">
+    <th class="logger_listing_narrow">&nbsp;</th>
+    <th class="logger_listing_narrow">&nbsp;</th>  
+    <th class="logger_listing_narrow">&nbsp;</th>  
+    <th class="logger_listing_narrow">&nbsp;</th>
+    <th class="logger_listing_narrow">@variable.unit@</th>
+    <th class="logger_listing_narrow">&nbsp;</th>
+    <th class="logger_listing_narrow">&nbsp;</th>
+  </tr>
 
   </table>
 </else>
Index: openacs-4/packages/logger/www/lib/entries-table.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/logger/www/lib/Attic/entries-table.tcl,v
diff -u -r1.5.2.2 -r1.5.2.3
--- openacs-4/packages/logger/www/lib/entries-table.tcl	13 May 2003 15:42:42 -0000	1.5.2.2
+++ openacs-4/packages/logger/www/lib/entries-table.tcl	15 May 2003 08:49:36 -0000	1.5.2.3
@@ -8,6 +8,7 @@
 #   start_date_ansi
 #   end_date_ansi 
 #   projection_value
+#   group_by:optional
 
 set current_user_id [ad_conn user_id]
 set package_id [ad_conn package_id]
@@ -48,10 +49,27 @@
     set selected_entry_id {}
 }
 
+set order_by "le.time_stamp desc, ao.creation_date desc"
+
+# If we're grouping by, we should sort by that column first
+if { [exists_and_not_null group_by] } {
+    switch -exact $group_by {
+        user_id {
+            set order_by "user_name asc, $order_by"
+        }
+        project_name {
+            set order_by "project_name asc, $order_by"
+        }
+    }
+}
+
 set value_total 0
 set value_count 0
 
-db_multirow -extend { view_url edit_url delete_url delete_onclick user_chunk selected_p } entries select_entries {} {
+set last_group_by_value {}
+set value_subtotal 0
+
+db_multirow -extend { subtotal view_url edit_url delete_url delete_onclick user_chunk selected_p } entries select_entries {} {
     set description [string_truncate -len 50 $description]
     set project_name [string_truncate -len 20 $project_name]
     set selected_p [string equal $id $selected_entry_id]
@@ -67,6 +85,20 @@
     
     set user_chunk [ad_present_user $user_id $user_name]
 
+    if { [exists_and_not_null group_by] } {
+        # Should we reset the subtotal?
+        if { ![string equal $last_group_by_value [set $group_by]] } {
+            set value_subtotal 0
+        }
+        
+        # Calculate new subtotal
+        set value_subtotal [expr $value_subtotal + $value]
+        # and store it in the column
+        set subtotal $value_subtotal
+
+        set last_group_by_value [set $group_by]
+    }
+
     set value_total [expr $value_total + $value]
     incr value_count
 }