Commit acb2356e authored by Frank Bergmann's avatar Frank Bergmann

- Gustaf changes

parent 95a1568f
......@@ -355,7 +355,7 @@ ad_proc -public im_sla_ticket_solution_time_sweeper {
the limit is set to 100 by default.
} {
ns_log Notice "im_sla_ticket_solution_time_sweeper: starting"
set traffic_light_limit [expr $limit * 1000]
set traffic_light_limit [expr {$limit * 1000}]
# Make sure that only one thread is calculating at a time
if {[nsv_incr intranet_sla_management sweeper_p] > 1} {
......@@ -564,17 +564,17 @@ ad_proc -public im_sla_ticket_traffic_light_sweeper_helper {
set color ""
if {[catch {
if {"" != $green_expr && [expr $green_expr]} { set color [im_project_on_track_status_green] }
if {"" != $green_expr && [expr {$green_expr}]} { set color [im_project_on_track_status_green] }
} err_msg]} {
ns_log Error "im_sla_ticket_traffic_light_sweeper_helper: #$ticket_id: Error evaluating green_expr=$green_expr: $err_msg"
}
if {[catch {
if {"" != $yellow_expr && [expr $yellow_expr]} { set color [im_project_on_track_status_yellow] }
if {"" != $yellow_expr && [expr {$yellow_expr}]} { set color [im_project_on_track_status_yellow] }
} err_msg]} {
ns_log Error "im_sla_ticket_traffic_light_sweeper_helper: #$ticket_id: Error evaluating yellow_expr=$yellow_expr: $err_msg"
}
if {[catch {
if {"" != $red_expr && [expr $red_expr]} { set color [im_project_on_track_status_red] }
if {"" != $red_expr && [expr {$red_expr}]} { set color [im_project_on_track_status_red] }
} err_msg]} {
ns_log Error "im_sla_ticket_traffic_light_sweeper_helper: #$ticket_id: Error evaluating red_expr=$red_expr: $err_msg"
}
......@@ -764,9 +764,9 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
set start_julian($ticket_id) $ticket_creation_julian
set start_epoch($ticket_id) $ticket_creation_epoch
set end_julian($ticket_id) $now_julian
set epoch_{$ticket_id}([expr $ticket_creation_epoch - 0.0003]) "creation"
set epoch_{$ticket_id}([expr {$ticket_creation_epoch - 0.0003}]) "creation"
set julian_{$ticket_id}($ticket_creation_julian) "creation"
set epoch_{$ticket_id}([expr $now_epoch + 0.0003]) "now"
set epoch_{$ticket_id}([expr {$now_epoch + 0.0003}]) "now"
set julian_{$ticket_id}($now_julian) "now"
if {$debug_p} { append time_html "<li>sla_id=$sla_id, $ticket_id: ticket_creation_epoch=$ticket_creation_epoch" }
......@@ -799,12 +799,12 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
set service_start_minute [string trimleft [lindex $service_start_list 1] "0"]
if {"" == $service_start_hour} { set service_start_hour 0 }
if {"" == $service_start_minute} { set service_start_minute 0 }
set service_start_epoch [expr [im_date_julian_to_epoch $j] + 3600.0*$service_start_hour + 60.0*$service_start_minute + 0.01]
set service_start_epoch [expr {[im_date_julian_to_epoch $j] + 3600.0*$service_start_hour + 60.0*$service_start_minute + 0.01}]
set epoch_{$ticket_id}($service_start_epoch) "service_start"
if {$debug_p} {
ns_log Notice "im_sla_ticket_solution_time: ticket_id=$ticket_id, service_start=$service_start, hour=$service_start_hour, min=$service_start_minute"
set service_start_epoch2 [db_string epoch "select extract(epoch from to_timestamp('$j $service_start', 'J HH24:MM')) + 0.01"]
ns_log Notice "im_sla_ticket_solution_time: diff=[expr $service_start_epoch - $service_start_epoch2]"
ns_log Notice "im_sla_ticket_solution_time: diff=[expr {$service_start_epoch - $service_start_epoch2}]"
append debug_html "<li>Start: julian=$j, ansi=[im_date_julian_to_ansi $j], service_start=$service_start, service_start_epoch=$service_start_epoch\n"
}
......@@ -818,12 +818,12 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
set service_end_minute [string trimleft [lindex $service_end_list 1] "0"]
if {"" == $service_end_hour} { set service_end_hour 0 }
if {"" == $service_end_minute} { set service_end_minute 0 }
set service_end_epoch [expr [im_date_julian_to_epoch $j] + 3600.0*$service_end_hour + 60.0*$service_end_minute + 0.01]
set service_end_epoch [expr {[im_date_julian_to_epoch $j] + 3600.0*$service_end_hour + 60.0*$service_end_minute + 0.01}]
set epoch_{$ticket_id}($service_end_epoch) "service_end"
if {$debug_p} {
ns_log Notice "im_sla_ticket_solution_time: ticket_id=$ticket_id, service_end=$service_end, hour=$service_end_hour, min=$service_end_minute"
set service_end_epoch2 [db_string epoch "select extract(epoch from to_timestamp('$j $service_end', 'J HH24:MM')) + 0.01"]
ns_log Notice "im_sla_ticket_solution_time: diff=[expr $service_end_epoch - $service_end_epoch2]"
ns_log Notice "im_sla_ticket_solution_time: diff=[expr {$service_end_epoch - $service_end_epoch2}]"
append debug_html "<li>End: julian=$j, ansi=[im_date_julian_to_ansi $j], service_end=$service_end, service_end_epoch=$service_end_epoch\n"
}
}
......@@ -849,7 +849,7 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
set labour_start_minute [string trimleft [lindex $labour_start_list 1] "0"]
if {"" == $labour_start_hour} { set labour_start_hour 0 }
if {"" == $labour_start_minute} { set labour_start_minute 0 }
set labour_start_epoch [expr [im_date_julian_to_epoch $j] + 3600.0*$labour_start_hour + 60.0*$labour_start_minute + 0.04]
set labour_start_epoch [expr {[im_date_julian_to_epoch $j] + 3600.0*$labour_start_hour + 60.0*$labour_start_minute + 0.04}]
set epoch_{$ticket_id}($labour_start_epoch) "labour_start"
# Write the affected groups into a hash
......@@ -866,7 +866,7 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
if {$debug_p} {
ns_log Notice "im_sla_ticket_solution_time: ticket_id=$ticket_id, labour_start=$labour_start, hour=$labour_start_hour, min=$labour_start_minute"
set labour_start_epoch2 [db_string epoch "select extract(epoch from to_timestamp('$j $labour_start', 'J HH24:MM')) + 0.04"]
ns_log Notice "im_sla_ticket_solution_time: diff=[expr $labour_start_epoch - $labour_start_epoch2]"
ns_log Notice "im_sla_ticket_solution_time: diff=[expr {$labour_start_epoch - $labour_start_epoch2}]"
append debug_html "<li>Labour Start: julian=$j, ansi=[im_date_julian_to_ansi $j], labour_start=$labour_start, labour_start_epoch=$labour_start_epoch\n"
}
......@@ -880,7 +880,7 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
set labour_end_minute [string trimleft [lindex $labour_end_list 1] "0"]
if {"" == $labour_end_hour} { set labour_end_hour 0 }
if {"" == $labour_end_minute} { set labour_end_minute 0 }
set labour_end_epoch [expr [im_date_julian_to_epoch $j] + 3600.0*$labour_end_hour + 60.0*$labour_end_minute + 0.04]
set labour_end_epoch [expr {[im_date_julian_to_epoch $j] + 3600.0*$labour_end_hour + 60.0*$labour_end_minute + 0.04}]
set epoch_{$ticket_id}($labour_end_epoch) "labour_end"
# Write the affected groups into a hash
set groups [list]
......@@ -890,7 +890,7 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
if {$debug_p} {
ns_log Notice "im_sla_ticket_solution_time: ticket_id=$ticket_id, labour_end=$labour_end, hour=$labour_end_hour, min=$labour_end_minute"
set labour_end_epoch2 [db_string epoch "select extract(epoch from to_timestamp('$j $labour_end', 'J HH24:MM')) + 0.04"]
ns_log Notice "im_sla_ticket_solution_time: diff=[expr $labour_end_epoch - $labour_end_epoch2]"
ns_log Notice "im_sla_ticket_solution_time: diff=[expr {$labour_end_epoch - $labour_end_epoch2}]"
append debug_html "<li>Labour End: julian=$j, ansi=[im_date_julian_to_ansi $j], labour_end=$labour_end, labour_end_epoch=$labour_end_epoch\n"
}
}
......@@ -1022,7 +1022,7 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
set event [lindex $event_full 0]
# Calculate duration since last event
set duration_epoch [expr $e - $last_epoch]
set duration_epoch [expr {$e - $last_epoch}]
# Which queue is responsible for the time passed?
if {[info exists queue_hash($e)]} {
......@@ -1046,7 +1046,7 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
foreach sh $labour_hours {
set labour_start [lindex $sh 0]
set labour_end [lindex $sh 1]
if {[string compare $labour_start $e_time] <= 0 && [string compare $e_time $labour_end] <= 0} {
if {$labour_start ne $e_time <= 0 && $e_time ne $labour_end <= 0} {
# The event's time ($e_time) is between start and end time
set ticket_labour_hour_p 1
}
......@@ -1069,13 +1069,13 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
}
service_start {
# Check if we were to count the duration until now
set count_duration_p [expr $ticket_open_p && $ticket_lifetime_p && $ticket_service_hour_p && $ticket_labour_hour_p]
set count_duration_p [expr {$ticket_open_p && $ticket_lifetime_p && $ticket_service_hour_p && $ticket_labour_hour_p}]
# Start counting the time from now on.
set ticket_service_hour_p 1
}
service_end {
# Check if we were to count the duration until now
set count_duration_p [expr $ticket_open_p && $ticket_lifetime_p && $ticket_service_hour_p && $ticket_labour_hour_p]
set count_duration_p [expr {$ticket_open_p && $ticket_lifetime_p && $ticket_service_hour_p && $ticket_labour_hour_p}]
# Don't count time from now on until the next service_start
set ticket_service_hour_p 0
}
......@@ -1086,7 +1086,7 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
if {-1 == [lsearch $affected_groups $queue_id]} { continue }
# Check if we were to count the duration until now
set count_duration_p [expr $ticket_open_p && $ticket_lifetime_p && $ticket_service_hour_p && $ticket_labour_hour_p]
set count_duration_p [expr {$ticket_open_p && $ticket_lifetime_p && $ticket_service_hour_p && $ticket_labour_hour_p}]
# Start counting the time from now on.
set ticket_labour_hour_p 1
}
......@@ -1097,13 +1097,13 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
if {-1 == [lsearch $affected_groups $queue_id]} { continue }
# Check if we were to count the duration until now
set count_duration_p [expr $ticket_open_p && $ticket_lifetime_p && $ticket_service_hour_p && $ticket_labour_hour_p]
set count_duration_p [expr {$ticket_open_p && $ticket_lifetime_p && $ticket_service_hour_p && $ticket_labour_hour_p}]
# Don't count time from now on until the next labour_start
set ticket_labour_hour_p 0
}
now {
# Check if we were to count the duration until now
set count_duration_p [expr $ticket_open_p && $ticket_lifetime_p && $ticket_service_hour_p && $ticket_labour_hour_p]
set count_duration_p [expr {$ticket_open_p && $ticket_lifetime_p && $ticket_service_hour_p && $ticket_labour_hour_p}]
# Current time. Don't count from here into the future...
set ticket_lifetime_p 0
}
......@@ -1118,7 +1118,7 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
}
# Check if we were to count the duration until now
set count_duration_p [expr $ticket_open_p && $ticket_lifetime_p && $ticket_service_hour_p && $ticket_labour_hour_p]
set count_duration_p [expr {$ticket_open_p && $ticket_lifetime_p && $ticket_service_hour_p && $ticket_labour_hour_p}]
# Determine ticket status"
if {[lsearch $ticket_open_states $event] > -1} {
......@@ -1133,13 +1133,13 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
if {$count_duration_p} {
# Total resolution time counter
set resolution_seconds [expr $resolution_seconds + $duration_epoch]
set resolution_seconds [expr {$resolution_seconds + $duration_epoch}]
# Resolution time per queue
if {"" != $last_queue_id} {
set seconds 0.0
if {[info exists queue_resolution_time($last_queue_id)]} { set seconds $queue_resolution_time($last_queue_id) }
set seconds [expr $seconds + $duration_epoch]
set seconds [expr {$seconds + $duration_epoch}]
set queue_resolution_time($last_queue_id) $seconds
}
}
......@@ -1155,20 +1155,20 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
set restime_html ""
foreach q [lsort -integer [array names queue_resolution_time]] {
set q_name [util_memoize [list db_string queue "select group_name from groups where group_id = $q" -default ""]]
append restime_html "$q_name=[expr round(100 * $queue_resolution_time($q)) / 100.0], "
append restime_html "$q_name=[expr {round(100 * $queue_resolution_time($q)) / 100.0}], "
}
append time_html "
<tr>
<td>[expr round(100.0 * $e) / 100.0]</td>
<td>[expr {round(100.0 * $e) / 100.0}]</td>
<td>[im_date_epoch_to_ansi $e] [im_date_epoch_to_time $e]</td>
<td><font color=$color><nobr>$event $event_pretty</nobr></font></td>
<td align=right>[expr round(100.0 * $duration_epoch) / 100.0]</td>
<td align=right>[expr {round(100.0 * $duration_epoch) / 100.0}]</td>
<td align=right>$count_duration_p</td>
<td>$last_queue_name</td>
<td>$queue_name</td>
<td align=right>[expr round(100.0 * $resolution_seconds) / 100.0]</td>
<td align=right>[expr round(100.0 * $resolution_seconds / 60.0) / 100.0 ]</td>
<td align=right>[expr round(100.0 * $resolution_seconds / 3600.0) / 100.0]</td>
<td align=right>[expr {round(100.0 * $resolution_seconds) / 100.0}]</td>
<td align=right>[expr {round(100.0 * $resolution_seconds / 60.0) / 100.0 }]</td>
<td align=right>[expr {round(100.0 * $resolution_seconds / 3600.0) / 100.0}]</td>
<td>$restime_html</td>
</tr>
"
......@@ -1193,7 +1193,7 @@ ad_proc -public im_sla_ticket_solution_time_sweeper_helper {
# Update the resolution time of the ticket
db_dml update_resolution_time "
update im_tickets set
ticket_resolution_time = [expr $resolution_seconds / 3600.0],
ticket_resolution_time = [expr {$resolution_seconds / 3600.0}],
ticket_resolution_time_dirty = now(),
ticket_resolution_time_per_queue = '{$restime_per_queue}'
where ticket_id = :ticket_id
......
<if @enable_master_p@><master></if>
<property name="title">@page_title@</property>
<property name="context">@context;noquote@</property>
<property name="doc(title)">@page_title;literal@</property>
<property name="context">@context;literal@</property>
<property name="main_navbar_label">helpdesk</property>
<property name="focus">@focus;noquote@</property>
<property name="sub_navbar">@sub_navbar;noquote@</property>
<property name="left_navbar">@left_navbar_html;noquote@</property>
<property name="focus">@focus;literal@</property>
<property name="sub_navbar">@sub_navbar;literal@</property>
<property name="left_navbar">@left_navbar_html;literal@</property>
<SCRIPT Language=JavaScript src=/resources/diagram/diagram/diagram.js></SCRIPT>
......
......@@ -25,7 +25,7 @@ ad_page_contract {
# Defaults & Security
# ---------------------------------------------------------------
set current_user_id [ad_maybe_redirect_for_registration]
set current_user_id [auth::require_login]
set page_title [lang::message::lookup "" intranet-sla-management.SLA_Parameter "SLA Parameter"]
if {[info exists param_id]} { set page_title [lang::message::lookup "" intranet-sla-management.SLA_parameter SLA_parameter] }
set context_bar [im_context_bar $page_title]
......
<master>
<property name="title">@page_title@</property>
<property name="doc(title)">@page_title;literal@</property>
<property name="context">#intranet-core.context#</property>
<property name="main_navbar_label">helpdesk</property>
......@@ -29,7 +29,7 @@
<tr>
<td></td>
<td><input type=submit name=submit value="Add User to Tickets"></td>
<td><input type="submit" name="submit" value="Add User to Tickets"></td>
<td></td>
</tr>
</table>
......@@ -55,7 +55,7 @@
<tr>
<td></td>
<td><input type=submit name=submit value="Add User to Tickets"></td>
<td><input type="submit" name="submit" value="Add User to Tickets"></td>
<td></td>
</tr>
</table>
......
......@@ -22,7 +22,7 @@ ad_page_contract {
# Defaults & Security
# ---------------------------------------------------------------
set current_user_id [ad_maybe_redirect_for_registration]
set current_user_id [auth::require_login]
set page_title [lang::message::lookup "" intranet-sla-management.Associate_Ticket_With_$target_object_type "Associate Ticket With $target_object_type"]
set context_bar [im_context_bar $page_title]
set page_focus "im_header_form.keywords"
......
<master>
<property name="title">@page_title@</property>
<property name="doc(title)">@page_title;literal@</property>
<property name="context">#intranet-core.context#</property>
<property name="main_navbar_label">helpdesk</property>
......@@ -14,13 +14,13 @@
<%= [export_vars -form {tid return_url}] %>
<table>
<tr>
<th colspan=2><%= [lang::message::lookup "" intranet-sla-management.Associate_With "Associate With"] %></th>
<th colspan="2"><%= [lang::message::lookup "" intranet-sla-management.Associate_With "Associate With"] %></th>
<th> <%= [lang::message::lookup "" intranet-sla-management.Object Object] %></th>
<th> <%= [lang::message::lookup "" intranet-sla-management.Comment Comment] %></th>
</tr>
<tr>
<td> <input type=radio name=target_object_type value=indicator checked></td>
<td> <input type="radio" name="target_object_type" value="indicator" checked></td>
<td> <%= [lang::message::lookup "" intranet-sla-management.Object_Type_Indicator "Indicator"] %></td>
<td> <%= [im_report_select -report_type_id [im_report_type_indicator] -indicator_object_type "im_sla_parameter" indicator_id] %><br>
</td>
......@@ -31,7 +31,7 @@
<tr>
<td>&nbsp;</td>
<td><input type=submit name=submit value="<%= [lang::message::lookup "" intranet-sla-management.Associate_Assoc_Action Associate] %>"></td>
<td><input type="submit" name="submit" value="<%= [lang::message::lookup "" intranet-sla-management.Associate_Assoc_Action Associate] %>"></td>
<td>&nbsp;</td>
</tr>
......
......@@ -19,7 +19,7 @@ ad_page_contract {
# Defaults & Security
# ---------------------------------------------------------------
set current_user_id [ad_maybe_redirect_for_registration]
set current_user_id [auth::require_login]
set page_title [lang::message::lookup "" intranet-helpdesk.Associate_Param_With_Other_Object "Associate SLA Parameter With Another Object"]
set context_bar [im_context_bar $page_title]
set page_focus "im_header_form.keywords"
......
......@@ -35,7 +35,7 @@ ad_page_contract {
set menu_label "reporting-sla-resolution-time-per-support-group"
# Get the current user and make sure that he or she is logged in.
set current_user_id [ad_maybe_redirect_for_registration]
set current_user_id [auth::require_login]
# Determine whether the current_user has read permissions.
set read_p [db_string report_perms "
......@@ -45,7 +45,7 @@ set read_p [db_string report_perms "
" -default 'f']
# Write out an error message if the current user doesn't have read permissions
if {![string equal "t" $read_p]} {
if {"t" ne $read_p } {
set message "You don't have the necessary permissions to view this page"
ad_return_complaint 1 "<li>$message"
ad_script_abort
......@@ -557,7 +557,7 @@ db_foreach sql $report_sql {
# a "hash", depending on the value of "counter".
# You need explicite evaluation ("expre") in TCL
# to calculate arithmetic expressions.
set class $rowclass([expr $counter % 2])
set class $rowclass([expr {$counter % 2}])
# Restrict the length of the project_name to max.
# 40 characters. (New!)
......@@ -575,11 +575,11 @@ db_foreach sql $report_sql {
# Calculated Variables (New!)
set po_per_quote_perc "undef"
if {[expr $quote_subtotal+0] != 0} {
set po_per_quote_perc [expr int(10000.0 * $po_subtotal / $quote_subtotal) / 100.0]
if {[expr {$quote_subtotal+0}] != 0} {
set po_per_quote_perc [expr {int(10000.0 * $po_subtotal / $quote_subtotal) / 100.0}]
set po_per_quote_perc "$po_per_quote_perc %"
}
set gross_profit [expr $invoice_subtotal - $bill_subtotal]
set gross_profit [expr {$invoice_subtotal - $bill_subtotal}]
set last_value_list [im_report_render_header \
-group_def $report_def \
......
# /packages/intranet-sla-management/sla-reaction-time.tcl
#
# Copyright (c) 2011 ]project-open[
#
# All rights reserved.
# Please see http://www.project-open.com/ for licensing.
ad_page_contract {
Show Reaction time per ticket
} {
{ start_date "" }
{ end_date "" }
{ level_of_detail:integer 3 }
{ customer_id:integer 0 }
{ ticket_type_id:integer 0 }
{ show_dynfields:multiple ""}
{ output_format "html" }
{ locale "es_ES" }
}
# ------------------------------------------------------------
# Security
#
set menu_label "reporting-helpdesk-sla-reaction-time"
set current_user_id [ad_maybe_redirect_for_registration]
set read_p [db_string report_perms "
select im_object_permission_p(m.menu_id, :current_user_id, 'read')
from im_menus m
where m.label = :menu_label
" -default 'f']
# For testing - set manually
set read_p "t"
if {![string equal "t" $read_p]} {
set message "You don't have the necessary permissions to view this page"
ad_return_complaint 1 "<li>$message"
ad_script_abort
}
set form_mode display
# set locale [lang::user::locale -user_id $current_user_id]
switch $locale {
en_US {
set number_format "999999999999.00"
}
default {
set number_format "999999999999,00"
}
}
# ------------------------------------------------------------
# Check Parameters
set days_in_past 7
db_1row todays_date "
select
to_char(sysdate::date - :days_in_past::integer, 'YYYY') as todays_year,
to_char(sysdate::date - :days_in_past::integer, 'MM') as todays_month,
to_char(sysdate::date - :days_in_past::integer, 'DD') as todays_day
from dual
"
if {"" == $start_date} {
set start_date "$todays_year-$todays_month-01"
}
db_1row end_date "
select
to_char(to_date(:start_date, 'YYYY-MM-DD') + '2 month'::interval, 'YYYY') as end_year,
to_char(to_date(:start_date, 'YYYY-MM-DD') + '2 month'::interval, 'MM') as end_month,
to_char(to_date(:start_date, 'YYYY-MM-DD') + '2 month'::interval, 'DD') as end_day
from dual
"
if {"" == $end_date} {
set end_date "$end_year-$end_month-01"
}
if {![regexp {[0-9][0-9][0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]} $start_date]} {
ad_return_complaint 1 "Start Date doesn't have the right format.<br>
Current value: '$start_date'<br>
Expected format: 'YYYY-MM-DD'"
ad_script_abort
}
if {![regexp {[0-9][0-9][0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]} $end_date]} {
ad_return_complaint 1 "End Date doesn't have the right format.<br>
Current value: '$end_date'<br>
Expected format: 'YYYY-MM-DD'"
ad_script_abort
}
# Maxlevel is 3.
if {$level_of_detail > 3} { set level_of_detail 3 }
# ------------------------------------------------------------
# Page Title, Bread Crums and Help
#
set page_title "Ticket Reaction Time"
set context_bar [im_context_bar $page_title]
set help_text "
<strong>$page_title</strong><br>
The report shows the 'reaction time' and various other times per ticket.<br>
The start- and end date act on the creation date of the ticket,
including start date but excluding end date.<br>
The report excludes tickets in the current status of 'canceled' and
'deleted'.
"
# ------------------------------------------------------------
# Default Values and Constants
set rowclass(0) "roweven"
set rowclass(1) "rowodd"
set currency_format "999,999,999.09"
set date_format "YYYY-MM-DD"
set date_time_format "YYYY-MM-DD HH24:MI"
set company_url "/intranet/companies/view"
set project_url "/intranet/projects/view"
set ticket_url "/intranet-helpdesk/new"
set invoice_url "/intranet-invoices/view"
set user_url "/intranet/users/view"
set this_url [export_vars -base "/intranet-sla-management/reports/sla-reaction-time" {start_date end_date} ]
# Level of Details
set levels {2 "Customer+SLA" 3 "All Details"}
# ------------------------------------------------------------
# Report Definition
#
# Reports are defined in a "declarative" style. The definition
# consists of a number of fields for header, lines and footer.
# Global Header Line
set header0 [list \
[lang::message::lookup "" intranet-sla-management.Ticket_Customer "Customer"] \
[lang::message::lookup "" intranet-sla-management.Ticket_SLA "SLA"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Customer_Contact "Customer<br>Contact"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Name "Ticket<br>Name"] \
[lang::message::lookup "" intranet-sla-management.Creation_User "Creation<br>User"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Creation_Time "Creation<br>Time"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Reaction_Time "Reaction<br>Time"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Confirmation_Time "Confirmation<br>Time"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Done_Time "Done<br>Time"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Signoff_Time "Signoff<br>Time"] \
]
# Global Footer Line
set footer0 {
"$ticket_reaction_time_total_count"
""
""
""
""
""
""
""
""
""
}
set customer_header {
"\#colspan=99 <b><a href=[export_vars -base $company_url {{company_id $company_id}}]>$company_name</a></b>"
}
set sla_header {
""
"\#colspan=98 <b><a href=[export_vars -base $project_url {{project_id $sla_id}}]>$sla_name</a></b>"
}
set sla_footer {
"$ticket_reaction_time_sla_count"
"$sla_nr"
""
""
""
""
""
""
""
""
}
set ticket_header {
"$ticket_reaction_time_sla_count"
"$sla_nr"
"<a href=[export_vars -base $user_url {{user_id $ticket_customer_contact_id}}]>$ticket_customer_contact_name</a>"
"<a href=[export_vars -base $ticket_url {{ticket_id $ticket_id} form_mode}]>$project_nr - $project_name_pretty</a>"
"<a href=[export_vars -base $user_url {{user_id $creation_user}}]>$creation_user_name</a>"
"$ticket_creation_date_pretty"
"$ticket_reaction_date_pretty"
"$ticket_confirmation_date_pretty"
"$ticket_done_date_pretty"
"$ticket_signoff_date_pretty"
}
set counters [list]
# Counters for reaction time per SLA and total
lappend counters [list pretty_name "Solution Time SLA Count" var ticket_reaction_time_sla_count reset "\$sla_id" expr "1"]
lappend counters [list pretty_name "Solution Time Total Count" var ticket_reaction_time_total_count reset 0 expr "1"]
set ticket_reaction_time_sla_count 0
set ticket_reaction_time_total_count 0
# ------------------------------------------------------------
# Add all Project and Company DynFields to list
set dynfield_sql "
select aa.attribute_name,
aa.pretty_name,
w.widget as tcl_widget,
w.widget_name as dynfield_widget,
w.deref_plpgsql_function
from im_dynfield_attributes a,
im_dynfield_widgets w,
acs_attributes aa
where a.widget_name = w.widget_name and
a.acs_attribute_id = aa.attribute_id and
aa.object_type = 'im_ticket' and
aa.attribute_name not like 'default%' and
aa.attribute_name not in (
-- Fields already hard coded in the report
'ticket_customer_contact_id'
)
order by
a.also_hard_coded_p DESC,
aa.object_type,
aa.sort_order
"
ns_log Notice "sla-reaction-time: show_dynfields=$show_dynfields"
set derefs [list "1 as one"]
set dynfield_options {}
db_foreach dynfield_attributes $dynfield_sql {
# Skip the DynField completely if the columns doesn't exist (Dynfield configuration errors)
if {![im_column_exists "im_tickets" $attribute_name]} { continue }
# Add the dynfield to the list of options
if {[lsearch $show_dynfields $attribute_name] > -1} { set selected "selected" } else { set selected "" }
append dynfield_options "\t\t<option value=$attribute_name $selected>$pretty_name</option>\n"
# Has the Dynfield been selected to be shown?
if {[lsearch $show_dynfields $attribute_name] < 0} {
ns_log Notice "sla-reaction-time: skipping $attribute_name"
continue
} else {
ns_log Notice "sla-reaction-time: showing $attribute_name"
}
# Calculate the "dereference" DynField value
set deref "substring(${deref_plpgsql_function}($attribute_name)::text for 100) as ${attribute_name}_deref"
if {"" == $deref} { set deref "substring($attribute_name::text for 100) as ${attribute_name}_deref" }
regsub -all {[^a-zA-Z0-9\ \-\.]} $pretty_name {} pretty_name
lappend header0 $pretty_name
lappend footer0 ""
lappend sla_footer ""
lappend derefs $deref
set var_name "\$${attribute_name}_deref"
lappend ticket_header $var_name
}
# ----------------------------------------------------------------
# The entries in this list include <a HREF=...> tags
# in order to link the entries to the rest of the system (New!)
# ----------------------------------------------------------------
#
set report_def [list \
group_by company_id \
header $customer_header \
content [list \
group_by sla_id \
header $sla_header \
content [list \
group_by ticket_id \
header $ticket_header \
content {} \
footer {} \
] \
footer $sla_footer \
]\
footer {} \
]
# ------------------------------------------------------------
# Report SQL - This SQL statement defines the raw data
# that are to be shown.
set criteria [list]
if {0 != $customer_id && "" != $customer_id} {
lappend criteria "p.company_id = :customer_id"
}
if {0 != $ticket_type_id && "" != $ticket_type_id} {
lappend criteria "t.ticket_type_id in (select * from im_sub_categories(:ticket_type_id))"
}
set where_clause [join $criteria " and\n\t\t"]
if { ![empty_string_p $where_clause] } { set where_clause " and $where_clause" }
set report_sql "
select
o.*,
im_name_from_user_id(o.creation_user) as creation_user_name,
to_char(o.creation_date, :date_time_format) as creation_date_pretty,
t.*,
im_category_from_id(t.ticket_status_id) as ticket_status,
im_category_from_id(t.ticket_type_id) as ticket_type,
im_name_from_user_id(t.ticket_assignee_id) as ticket_assignee,
to_char(t.ticket_creation_date, :date_time_format) as ticket_creation_date_pretty,
to_char(t.ticket_reaction_date, :date_time_format) as ticket_reaction_date_pretty,
t.ticket_reaction_date - o.creation_date as ticket_reaction_interval,
to_char(t.ticket_done_date, :date_time_format) as ticket_done_date_pretty,
t.ticket_done_date - o.creation_date as ticket_done_interval,
to_char(t.ticket_confirmation_date, :date_time_format) as ticket_confirmation_date_pretty,
to_char(t.ticket_signoff_date, :date_time_format) as ticket_signoff_date_pretty,
im_name_from_user_id(t.ticket_customer_contact_id) as ticket_customer_contact_name,
p.*,
substring(p.project_name for 30) as project_name_pretty,
g.*,
g.group_name as ticket_queue,
cust.*,
im_category_from_id(cust.company_type_id) as company_type,
sla_project.project_id as sla_id,
sla_project.project_nr as sla_nr,
sla_project.project_name as sla_name,
[join $derefs "\t,\n"]
from
acs_objects o,
im_projects p
LEFT OUTER JOIN im_companies cust ON (p.company_id = cust.company_id)
LEFT OUTER JOIN im_offices office ON (office.office_id = cust.main_office_id)
LEFT OUTER JOIN im_projects sla_project ON (p.parent_id = sla_project.project_id),
im_tickets t
LEFT OUTER JOIN persons p_contact ON (t.ticket_customer_contact_id = p_contact.person_id)
LEFT OUTER JOIN parties pa_contact ON (t.ticket_customer_contact_id = pa_contact.party_id)
LEFT OUTER JOIN groups g ON (t.ticket_queue_id = g.group_id)
where
t.ticket_id = o.object_id and
t.ticket_id = p.project_id and
t.ticket_creation_date >= :start_date and
t.ticket_creation_date < :end_date and
t.ticket_status_id not in (
[im_ticket_status_deleted],
[im_ticket_status_canceled]
)
$where_clause
order by
lower(cust.company_name),
lower(sla_project.project_name),
lower(im_name_from_user_id(o.creation_user)),
lower(p.project_nr)
"
# --------------------------------------------------------
# Write out HTTP header, considering CSV/MS-Excel formatting
im_report_write_http_headers -output_format $output_format
switch $output_format {
html {
ns_write "
[im_header]
[im_navbar]
<form>
<table cellspacing=10 cellpadding=0 border=0>
<tr valign=top>
<td>
<!-- 'Filters' - Show the Report parameters -->
<table cellspacing=2>
<tr class=rowtitle>
<td class=rowtitle colspan=2 align=center>Filters</td>
</tr>
<tr>
<td class=form-label>Level of Details</td>
<td class=form-widget>
[im_select -translate_p 0 level_of_detail $levels $level_of_detail]
</td>
</tr>
<tr>
<td><nobr>Start Date:</nobr></td>
<td><input type=text name=start_date value='$start_date'></td>
</tr>
<tr>
<td>End Date:</td>
<td><input type=text name=end_date value='$end_date'></td>
</tr>
<tr>
<td class=form-label>Ticket Type</td>
<td class=form-widget>
[im_category_select -include_empty_p 1 -include_empty_name [lang::message::lookup "" intranet-core.All "All"] "Intranet Ticket Type" ticket_type_id $ticket_type_id]
</td>
</tr>
<tr>
<td>[lang::message::lookup "" intranet-sla-management.Customer "Customer"]</td>
<td>[im_company_select -include_empty_name [lang::message::lookup "" intranet-core.All "All"] customer_id $customer_id]</td>
</tr>
<tr>
<td class=form-label>Format</td>
<td class=form-widget>
[im_report_output_format_select output_format "" $output_format]
</td>
</tr>
<tr>
<td</td>
<td><input type=submit value='Submit'></td>
</tr>
</table>
</td>
<td align=center>
<table cellspacing=2>
<tr class=rowtitle>
<td class=rowtitle align=center>
[lang::message::lookup "" intranet-sla-management.Additional_Fields "Additional Fields"]
</td>
</tr>
<tr>
<td>
<select name=show_dynfields size=6 multiple>
$dynfield_options
</select>
</td>
</tr>
</table>
</td>
<td align=center>
<table cellspacing=2>
<tr>
<td>$help_text</td>
</tr>
</table>
</td>
</tr>
</table>
</form>
<!-- Here starts the main report table -->
<table border=0 cellspacing=1 cellpadding=1>
"
}
printer {
ns_write "
<link rel=StyleSheet type='text/css' href='/intranet-reporting/printer-friendly.css' media=all>
<div class=\"fullwidth-list\">
<table border=0 cellspacing=1 cellpadding=1 rules=all>
<colgroup>
<col id=datecol>
<col id=hourcol>
<col id=datecol>
<col id=datecol>
<col id=hourcol>
<col id=hourcol>
<col id=hourcol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
</colgroup>
"
}
}
set footer_array_list [list]
set last_value_list [list]
im_report_render_row \
-output_format $output_format \
-row $header0 \
-row_class "rowtitle" \
-cell_class "rowtitle"
set counter 0
set class ""
db_foreach sql $report_sql {
# Select either "roweven" or "rowodd" from
# a "hash", depending on the value of "counter".
# You need explicite evaluation ("expre") in TCL
# to calculate arithmetic expressions.
set class $rowclass([expr $counter % 2])
im_report_display_footer \
-output_format $output_format \
-group_def $report_def \
-footer_array_list $footer_array_list \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-row_class $class \
-cell_class $class
im_report_update_counters -counters $counters
if {"" != $ticket_type} {
set category_key "intranet-core.[lang::util::suggest_key $ticket_type]"
set ticket_type [lang::message::lookup $locale $category_key $ticket_type]
}
if {"" != $company_type} {
set category_key "intranet-core.[lang::util::suggest_key $company_type]"
set company_type [lang::message::lookup $locale $category_key $company_type]
}
if {"Employees" == $ticket_queue} { set ticket_queue "" }
set last_value_list [im_report_render_header \
-output_format $output_format \
-group_def $report_def \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-row_class $class \
-cell_class $class
]
set footer_array_list [im_report_render_footer \
-output_format $output_format \
-group_def $report_def \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-row_class $class \
-cell_class $class
]
incr counter
}
im_report_display_footer \
-output_format $output_format \
-group_def $report_def \
-footer_array_list $footer_array_list \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-display_all_footers_p 1 \
-row_class $class \
-cell_class $class
# Calculate fields for totoal (footer0)
# which can be undefined.
set ticket_reaction_time_total_median 0.00
catch { set ticket_reaction_time_total_median [expr $ticket_reaction_time_total_sum / $ticket_reaction_time_total_count] }
im_report_render_row \
-output_format $output_format \
-row $footer0 \
-row_class $class \
-cell_class $class \
-upvar_level 1
ns_log Notice "report-tickets: $output_format"
# Write out the HTMl to close the main report table
# and write out the page footer.
#
switch $output_format {
html { ns_write "</table>[im_footer]\n" }
printer { ns_write "</table>\n</div>\n" }
cvs { }
}
# /packages/intranet-sla-management/sla-reaction-time.tcl
#
# Copyright (c) 2011 ]project-open[
#
# All rights reserved.
# Please see http://www.project-open.com/ for licensing.
ad_page_contract {
Show Reaction time per ticket
} {
{ start_date "" }
{ end_date "" }
{ level_of_detail:integer 3 }
{ customer_id:integer 0 }
{ ticket_type_id:integer 0 }
{ show_dynfields:multiple ""}
{ output_format "html" }
{ locale "es_ES" }
}
# ------------------------------------------------------------
# Security
#
set menu_label "reporting-helpdesk-sla-reaction-time"
set current_user_id [auth::require_login]
set read_p [db_string report_perms "
select im_object_permission_p(m.menu_id, :current_user_id, 'read')
from im_menus m
where m.label = :menu_label
" -default 'f']
# For testing - set manually
set read_p "t"
if {"t" ne $read_p } {
set message "You don't have the necessary permissions to view this page"
ad_return_complaint 1 "<li>$message"
ad_script_abort
}
set form_mode display
# set locale [lang::user::locale -user_id $current_user_id]
switch $locale {
en_US {
set number_format "999999999999.00"
}
default {
set number_format "999999999999,00"
}
}
# ------------------------------------------------------------
# Check Parameters
set days_in_past 7
db_1row todays_date "
select
to_char(sysdate::date - :days_in_past::integer, 'YYYY') as todays_year,
to_char(sysdate::date - :days_in_past::integer, 'MM') as todays_month,
to_char(sysdate::date - :days_in_past::integer, 'DD') as todays_day
from dual
"
if {"" == $start_date} {
set start_date "$todays_year-$todays_month-01"
}
db_1row end_date "
select
to_char(to_date(:start_date, 'YYYY-MM-DD') + '2 month'::interval, 'YYYY') as end_year,
to_char(to_date(:start_date, 'YYYY-MM-DD') + '2 month'::interval, 'MM') as end_month,
to_char(to_date(:start_date, 'YYYY-MM-DD') + '2 month'::interval, 'DD') as end_day
from dual
"
if {"" == $end_date} {
set end_date "$end_year-$end_month-01"
}
if {![regexp {[0-9][0-9][0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]} $start_date]} {
ad_return_complaint 1 "Start Date doesn't have the right format.<br>
Current value: '$start_date'<br>
Expected format: 'YYYY-MM-DD'"
ad_script_abort
}
if {![regexp {[0-9][0-9][0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]} $end_date]} {
ad_return_complaint 1 "End Date doesn't have the right format.<br>
Current value: '$end_date'<br>
Expected format: 'YYYY-MM-DD'"
ad_script_abort
}
# Maxlevel is 3.
if {$level_of_detail > 3} { set level_of_detail 3 }
# ------------------------------------------------------------
# Page Title, Bread Crums and Help
#
set page_title "Ticket Reaction Time"
set context_bar [im_context_bar $page_title]
set help_text "
<strong>$page_title</strong><br>
The report shows the 'reaction time' and various other times per ticket.<br>
The start- and end date act on the creation date of the ticket,
including start date but excluding end date.<br>
The report excludes tickets in the current status of 'canceled' and
'deleted'.
"
# ------------------------------------------------------------
# Default Values and Constants
set rowclass(0) "roweven"
set rowclass(1) "rowodd"
set currency_format "999,999,999.09"
set date_format "YYYY-MM-DD"
set date_time_format "YYYY-MM-DD HH24:MI"
set company_url "/intranet/companies/view"
set project_url "/intranet/projects/view"
set ticket_url "/intranet-helpdesk/new"
set invoice_url "/intranet-invoices/view"
set user_url "/intranet/users/view"
set this_url [export_vars -base "/intranet-sla-management/reports/sla-reaction-time" {start_date end_date} ]
# Level of Details
set levels {2 "Customer+SLA" 3 "All Details"}
# ------------------------------------------------------------
# Report Definition
#
# Reports are defined in a "declarative" style. The definition
# consists of a number of fields for header, lines and footer.
# Global Header Line
set header0 [list \
[lang::message::lookup "" intranet-sla-management.Ticket_Customer "Customer"] \
[lang::message::lookup "" intranet-sla-management.Ticket_SLA "SLA"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Customer_Contact "Customer<br>Contact"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Name "Ticket<br>Name"] \
[lang::message::lookup "" intranet-sla-management.Creation_User "Creation<br>User"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Creation_Time "Creation<br>Time"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Reaction_Time "Reaction<br>Time"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Confirmation_Time "Confirmation<br>Time"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Done_Time "Done<br>Time"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Signoff_Time "Signoff<br>Time"] \
]
# Global Footer Line
set footer0 {
"$ticket_reaction_time_total_count"
""
""
""
""
""
""
""
""
""
}
set customer_header {
"\#colspan=99 <b><a href=[export_vars -base $company_url {{company_id $company_id}}]>$company_name</a></b>"
}
set sla_header {
""
"\#colspan=98 <b><a href=[export_vars -base $project_url {{project_id $sla_id}}]>$sla_name</a></b>"
}
set sla_footer {
"$ticket_reaction_time_sla_count"
"$sla_nr"
""
""
""
""
""
""
""
""
}
set ticket_header {
"$ticket_reaction_time_sla_count"
"$sla_nr"
"<a href=[export_vars -base $user_url {{user_id $ticket_customer_contact_id}}]>$ticket_customer_contact_name</a>"
"<a href=[export_vars -base $ticket_url {{ticket_id $ticket_id} form_mode}]>$project_nr - $project_name_pretty</a>"
"<a href=[export_vars -base $user_url {{user_id $creation_user}}]>$creation_user_name</a>"
"$ticket_creation_date_pretty"
"$ticket_reaction_date_pretty"
"$ticket_confirmation_date_pretty"
"$ticket_done_date_pretty"
"$ticket_signoff_date_pretty"
}
set counters [list]
# Counters for reaction time per SLA and total
lappend counters [list pretty_name "Solution Time SLA Count" var ticket_reaction_time_sla_count reset "\$sla_id" expr "1"]
lappend counters [list pretty_name "Solution Time Total Count" var ticket_reaction_time_total_count reset 0 expr "1"]
set ticket_reaction_time_sla_count 0
set ticket_reaction_time_total_count 0
# ------------------------------------------------------------
# Add all Project and Company DynFields to list
set dynfield_sql "
select aa.attribute_name,
aa.pretty_name,
w.widget as tcl_widget,
w.widget_name as dynfield_widget,
w.deref_plpgsql_function
from im_dynfield_attributes a,
im_dynfield_widgets w,
acs_attributes aa
where a.widget_name = w.widget_name and
a.acs_attribute_id = aa.attribute_id and
aa.object_type = 'im_ticket' and
aa.attribute_name not like 'default%' and
aa.attribute_name not in (
-- Fields already hard coded in the report
'ticket_customer_contact_id'
)
order by
a.also_hard_coded_p DESC,
aa.object_type,
aa.sort_order
"
ns_log Notice "sla-reaction-time: show_dynfields=$show_dynfields"
set derefs [list "1 as one"]
set dynfield_options {}
db_foreach dynfield_attributes $dynfield_sql {
# Skip the DynField completely if the columns doesn't exist (Dynfield configuration errors)
if {![im_column_exists "im_tickets" $attribute_name]} { continue }
# Add the dynfield to the list of options
if {[lsearch $show_dynfields $attribute_name] > -1} { set selected "selected" } else { set selected "" }
append dynfield_options "\t\t<option value=$attribute_name $selected>$pretty_name</option>\n"
# Has the Dynfield been selected to be shown?
if {[lsearch $show_dynfields $attribute_name] < 0} {
ns_log Notice "sla-reaction-time: skipping $attribute_name"
continue
} else {
ns_log Notice "sla-reaction-time: showing $attribute_name"
}
# Calculate the "dereference" DynField value
set deref "substring(${deref_plpgsql_function}($attribute_name)::text for 100) as ${attribute_name}_deref"
if {"" == $deref} { set deref "substring($attribute_name::text for 100) as ${attribute_name}_deref" }
regsub -all {[^a-zA-Z0-9\ \-\.]} $pretty_name {} pretty_name
lappend header0 $pretty_name
lappend footer0 ""
lappend sla_footer ""
lappend derefs $deref
set var_name "\$${attribute_name}_deref"
lappend ticket_header $var_name
}
# ----------------------------------------------------------------
# The entries in this list include <a HREF=...> tags
# in order to link the entries to the rest of the system (New!)
# ----------------------------------------------------------------
#
set report_def [list \
group_by company_id \
header $customer_header \
content [list \
group_by sla_id \
header $sla_header \
content [list \
group_by ticket_id \
header $ticket_header \
content {} \
footer {} \
] \
footer $sla_footer \
]\
footer {} \
]
# ------------------------------------------------------------
# Report SQL - This SQL statement defines the raw data
# that are to be shown.
set criteria [list]
if {0 != $customer_id && "" != $customer_id} {
lappend criteria "p.company_id = :customer_id"
}
if {0 != $ticket_type_id && "" != $ticket_type_id} {
lappend criteria "t.ticket_type_id in (select * from im_sub_categories(:ticket_type_id))"
}
set where_clause [join $criteria " and\n\t\t"]
if { $where_clause ne "" } { set where_clause " and $where_clause" }
set report_sql "
select
o.*,
im_name_from_user_id(o.creation_user) as creation_user_name,
to_char(o.creation_date, :date_time_format) as creation_date_pretty,
t.*,
im_category_from_id(t.ticket_status_id) as ticket_status,
im_category_from_id(t.ticket_type_id) as ticket_type,
im_name_from_user_id(t.ticket_assignee_id) as ticket_assignee,
to_char(t.ticket_creation_date, :date_time_format) as ticket_creation_date_pretty,
to_char(t.ticket_reaction_date, :date_time_format) as ticket_reaction_date_pretty,
t.ticket_reaction_date - o.creation_date as ticket_reaction_interval,
to_char(t.ticket_done_date, :date_time_format) as ticket_done_date_pretty,
t.ticket_done_date - o.creation_date as ticket_done_interval,
to_char(t.ticket_confirmation_date, :date_time_format) as ticket_confirmation_date_pretty,
to_char(t.ticket_signoff_date, :date_time_format) as ticket_signoff_date_pretty,
im_name_from_user_id(t.ticket_customer_contact_id) as ticket_customer_contact_name,
p.*,
substring(p.project_name for 30) as project_name_pretty,
g.*,
g.group_name as ticket_queue,
cust.*,
im_category_from_id(cust.company_type_id) as company_type,
sla_project.project_id as sla_id,
sla_project.project_nr as sla_nr,
sla_project.project_name as sla_name,
[join $derefs "\t,\n"]
from
acs_objects o,
im_projects p
LEFT OUTER JOIN im_companies cust ON (p.company_id = cust.company_id)
LEFT OUTER JOIN im_offices office ON (office.office_id = cust.main_office_id)
LEFT OUTER JOIN im_projects sla_project ON (p.parent_id = sla_project.project_id),
im_tickets t
LEFT OUTER JOIN persons p_contact ON (t.ticket_customer_contact_id = p_contact.person_id)
LEFT OUTER JOIN parties pa_contact ON (t.ticket_customer_contact_id = pa_contact.party_id)
LEFT OUTER JOIN groups g ON (t.ticket_queue_id = g.group_id)
where
t.ticket_id = o.object_id and
t.ticket_id = p.project_id and
t.ticket_creation_date >= :start_date and
t.ticket_creation_date < :end_date and
t.ticket_status_id not in (
[im_ticket_status_deleted],
[im_ticket_status_canceled]
)
$where_clause
order by
lower(cust.company_name),
lower(sla_project.project_name),
lower(im_name_from_user_id(o.creation_user)),
lower(p.project_nr)
"
# --------------------------------------------------------
# Write out HTTP header, considering CSV/MS-Excel formatting
im_report_write_http_headers -output_format $output_format
switch $output_format {
html {
ns_write "
[im_header]
[im_navbar]
<form>
<table cellspacing=10 cellpadding=0 border=0>
<tr valign=top>
<td>
<!-- 'Filters' - Show the Report parameters -->
<table cellspacing=2>
<tr class=rowtitle>
<td class=rowtitle colspan=2 align=center>Filters</td>
</tr>
<tr>
<td class=form-label>Level of Details</td>
<td class=form-widget>
[im_select -translate_p 0 level_of_detail $levels $level_of_detail]
</td>
</tr>
<tr>
<td><nobr>Start Date:</nobr></td>
<td><input type=text name=start_date value='$start_date'></td>
</tr>
<tr>
<td>End Date:</td>
<td><input type=text name=end_date value='$end_date'></td>
</tr>
<tr>
<td class=form-label>Ticket Type</td>
<td class=form-widget>
[im_category_select -include_empty_p 1 -include_empty_name [lang::message::lookup "" intranet-core.All "All"] "Intranet Ticket Type" ticket_type_id $ticket_type_id]
</td>
</tr>
<tr>
<td>[lang::message::lookup "" intranet-sla-management.Customer "Customer"]</td>
<td>[im_company_select -include_empty_name [lang::message::lookup "" intranet-core.All "All"] customer_id $customer_id]</td>
</tr>
<tr>
<td class=form-label>Format</td>
<td class=form-widget>
[im_report_output_format_select output_format "" $output_format]
</td>
</tr>
<tr>
<td</td>
<td><input type=submit value='Submit'></td>
</tr>
</table>
</td>
<td align=center>
<table cellspacing=2>
<tr class=rowtitle>
<td class=rowtitle align=center>
[lang::message::lookup "" intranet-sla-management.Additional_Fields "Additional Fields"]
</td>
</tr>
<tr>
<td>
<select name=show_dynfields size=6 multiple>
$dynfield_options
</select>
</td>
</tr>
</table>
</td>
<td align=center>
<table cellspacing=2>
<tr>
<td>$help_text</td>
</tr>
</table>
</td>
</tr>
</table>
</form>
<!-- Here starts the main report table -->
<table border=0 cellspacing=1 cellpadding=1>
"
}
printer {
ns_write "
<link rel=StyleSheet type='text/css' href='/intranet-reporting/printer-friendly.css' media=all>
<div class=\"fullwidth-list\">
<table border=0 cellspacing=1 cellpadding=1 rules=all>
<colgroup>
<col id=datecol>
<col id=hourcol>
<col id=datecol>
<col id=datecol>
<col id=hourcol>
<col id=hourcol>
<col id=hourcol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
</colgroup>
"
}
}
set footer_array_list [list]
set last_value_list [list]
im_report_render_row \
-output_format $output_format \
-row $header0 \
-row_class "rowtitle" \
-cell_class "rowtitle"
set counter 0
set class ""
db_foreach sql $report_sql {
# Select either "roweven" or "rowodd" from
# a "hash", depending on the value of "counter".
# You need explicite evaluation ("expre") in TCL
# to calculate arithmetic expressions.
set class $rowclass([expr {$counter % 2}])
im_report_display_footer \
-output_format $output_format \
-group_def $report_def \
-footer_array_list $footer_array_list \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-row_class $class \
-cell_class $class
im_report_update_counters -counters $counters
if {"" != $ticket_type} {
set category_key "intranet-core.[lang::util::suggest_key $ticket_type]"
set ticket_type [lang::message::lookup $locale $category_key $ticket_type]
}
if {"" != $company_type} {
set category_key "intranet-core.[lang::util::suggest_key $company_type]"
set company_type [lang::message::lookup $locale $category_key $company_type]
}
if {"Employees" == $ticket_queue} { set ticket_queue "" }
set last_value_list [im_report_render_header \
-output_format $output_format \
-group_def $report_def \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-row_class $class \
-cell_class $class
]
set footer_array_list [im_report_render_footer \
-output_format $output_format \
-group_def $report_def \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-row_class $class \
-cell_class $class
]
incr counter
}
im_report_display_footer \
-output_format $output_format \
-group_def $report_def \
-footer_array_list $footer_array_list \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-display_all_footers_p 1 \
-row_class $class \
-cell_class $class
# Calculate fields for totoal (footer0)
# which can be undefined.
set ticket_reaction_time_total_median 0.00
catch { set ticket_reaction_time_total_median [expr {$ticket_reaction_time_total_sum / $ticket_reaction_time_total_count}] }
im_report_render_row \
-output_format $output_format \
-row $footer0 \
-row_class $class \
-cell_class $class \
-upvar_level 1
ns_log Notice "report-tickets: $output_format"
# Write out the HTMl to close the main report table
# and write out the page footer.
#
switch $output_format {
html { ns_write "</table>[im_footer]\n" }
printer { ns_write "</table>\n</div>\n" }
cvs { }
}
# /packages/intranet-sencha-ticket-tracker/report-tickets.tcl
#
# Copyright (c) 2011 ]project-open[
#
# All rights reserved.
# Please see http://www.project-open.com/ for licensing.
ad_page_contract {
Show Resolution time per ticket
} {
{ start_date "" }
{ end_date "" }
{ level_of_detail:integer 3 }
{ customer_id:integer 0 }
{ ticket_type_id:integer 0 }
{ show_dynfields:multiple ""}
{ output_format "html" }
{ locale "es_ES" }
}
# ------------------------------------------------------------
# Security
#
set menu_label "reporting-helpdesk-sla-resolution-time"
set current_user_id [ad_maybe_redirect_for_registration]
set read_p [db_string report_perms "
select im_object_permission_p(m.menu_id, :current_user_id, 'read')
from im_menus m
where m.label = :menu_label
" -default 'f']
# For testing - set manually
set read_p "t"
if {![string equal "t" $read_p]} {
set message "You don't have the necessary permissions to view this page"
ad_return_complaint 1 "<li>$message"
ad_script_abort
}
set form_mode display
# set locale [lang::user::locale -user_id $current_user_id]
switch $locale {
en_US {
set number_format "999999999999.00"
}
default {
set number_format "999999999999,00"
}
}
# ------------------------------------------------------------
# Check Parameters
# ------------------------------------------------------------
# Defaults
set days_in_past 7
db_1row todays_date "
select
to_char(sysdate::date - :days_in_past::integer, 'YYYY') as todays_year,
to_char(sysdate::date - :days_in_past::integer, 'MM') as todays_month,
to_char(sysdate::date - :days_in_past::integer, 'DD') as todays_day
from dual
"
if {"" == $start_date} {
set start_date "$todays_year-$todays_month-01"
}
db_1row end_date "
select
to_char(to_date(:start_date, 'YYYY-MM-DD') + '2 month'::interval, 'YYYY') as end_year,
to_char(to_date(:start_date, 'YYYY-MM-DD') + '2 month'::interval, 'MM') as end_month,
to_char(to_date(:start_date, 'YYYY-MM-DD') + '2 month'::interval, 'DD') as end_day
from dual
"
if {"" == $end_date} {
set end_date "$end_year-$end_month-01"
}
if {![regexp {[0-9][0-9][0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]} $start_date]} {
ad_return_complaint 1 "Start Date doesn't have the right format.<br>
Current value: '$start_date'<br>
Expected format: 'YYYY-MM-DD'"
ad_script_abort
}
if {![regexp {[0-9][0-9][0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]} $end_date]} {
ad_return_complaint 1 "End Date doesn't have the right format.<br>
Current value: '$end_date'<br>
Expected format: 'YYYY-MM-DD'"
ad_script_abort
}
# Maxlevel is 3.
if {$level_of_detail > 3} { set level_of_detail 3 }
# ------------------------------------------------------------
# Page Title, Bread Crums and Help
#
set page_title "Ticket Resolution Time"
set context_bar [im_context_bar $page_title]
set help_text "
<strong>$page_title</strong><br>
The report shows the 'resolution time' per ticket and ticket queue
together with median values per SLA and for all selected tickets.<br>
The start- and end date act on the creation date of the ticket,
including start date but excluding end date.<br>
The report excludes tickets in the current status of 'canceled' and
'deleted'.
"
# ------------------------------------------------------------
# Default Values and Constants
set rowclass(0) "roweven"
set rowclass(1) "rowodd"
set currency_format "999,999,999.09"
set date_format "YYYY-MM-DD"
set date_time_format "YYYY-MM-DD HH24:MI"
set company_url "/intranet/companies/view"
set project_url "/intranet/projects/view"
set ticket_url "/intranet-helpdesk/new"
set invoice_url "/intranet-invoices/view"
set user_url "/intranet/users/view"
set this_url [export_vars -base "/intranet-sla-management/reports/sla-resolution-time" {start_date end_date} ]
# Level of Details
set levels {2 "Customer+SLA" 3 "All Details"}
# ------------------------------------------------------------
# Report Definition
#
# Reports are defined in a "declarative" style. The definition
# consists of a number of fields for header, lines and footer.
# Global Header Line
set header0 [list \
[lang::message::lookup "" intranet-sla-management.Ticket_Customer "Customer"] \
[lang::message::lookup "" intranet-sla-management.Ticket_SLA "SLA"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Customer_Contact "Customer<br>Contact"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Name "Ticket<br>Name"] \
[lang::message::lookup "" intranet-sla-management.Creation_User "Creation<br>User"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Resolution_Time "Resolution<br>Time"] \
]
# Global Footer Line
set footer0 {
"$ticket_resolution_time_total_count"
""
""
""
""
"\#align=right \[lc_numeric \[expr round(100.0 * \$ticket_resolution_time_total_median) / 100.0\] {} \$locale\]"
}
set customer_header {
"\#colspan=99 <b><a href=[export_vars -base $company_url {{company_id $company_id}}]>$company_name</a></b>"
}
set sla_header {
""
"\#colspan=98 <b><a href=[export_vars -base $project_url {{project_id $sla_id}}]>$sla_name</a></b>"
}
set sla_footer {
"$ticket_resolution_time_sla_count"
"$sla_nr"
""
""
""
"\#align=right [lc_numeric [expr round(100.0 * $ticket_resolution_time_sla_sum / $ticket_resolution_time_sla_count) / 100.0] {} $locale]"
}
set ticket_header {
"$ticket_resolution_time_sla_count"
"$sla_nr"
"<a href=[export_vars -base $user_url {{user_id $ticket_customer_contact_id}}]>$ticket_customer_contact_name</a>"
"<a href=[export_vars -base $ticket_url {{ticket_id $ticket_id} form_mode}]>$project_nr - $project_name_pretty</a>"
"<a href=[export_vars -base $user_url {{user_id $creation_user}}]>$creation_user_name</a>"
"\#align=right \[lc_numeric $ticket_resolution_time {} $locale\]"
}
set counters [list]
# Counters for resolution time per SLA and total
lappend counters [list pretty_name "Solution Time SLA Sum" var ticket_resolution_time_sla_sum reset "\$sla_id" expr "\$ticket_resolution_time"]
lappend counters [list pretty_name "Solution Time SLA Count" var ticket_resolution_time_sla_count reset "\$sla_id" expr "1"]
lappend counters [list pretty_name "Solution Time Total Sum" var ticket_resolution_time_total_sum reset 0 expr "\$ticket_resolution_time"]
lappend counters [list pretty_name "Solution Time Total Count" var ticket_resolution_time_total_count reset 0 expr "1"]
set ticket_resolution_time_total_sum 0
set ticket_resolution_time_total_count 0
# ------------------------------------------------------------
# Add all Project and Company DynFields to list
set dynfield_sql "
select aa.attribute_name,
aa.pretty_name,
w.widget as tcl_widget,
w.widget_name as dynfield_widget,
w.deref_plpgsql_function
from im_dynfield_attributes a,
im_dynfield_widgets w,
acs_attributes aa
where a.widget_name = w.widget_name and
a.acs_attribute_id = aa.attribute_id and
aa.object_type = 'im_ticket' and
aa.attribute_name not like 'default%' and
aa.attribute_name not in (
-- Fields already hard coded in the report
'ticket_customer_contact_id'
)
order by
a.also_hard_coded_p DESC,
aa.object_type,
aa.sort_order
"
ns_log Notice "sla-resolution-time: show_dynfields=$show_dynfields"
set derefs [list "1 as one"]
set dynfield_options {}
db_foreach dynfield_attributes $dynfield_sql {
# Skip the DynField completely if the columns doesn't exist (Dynfield configuration errors)
if {![im_column_exists "im_tickets" $attribute_name]} { continue }
# Add the dynfield to the list of options
if {[lsearch $show_dynfields $attribute_name] > -1} { set selected "selected" } else { set selected "" }
append dynfield_options "\t\t<option value=$attribute_name $selected>$pretty_name</option>\n"
# Has the Dynfield been selected to be shown?
if {[lsearch $show_dynfields $attribute_name] < 0} {
ns_log Notice "sla-resolution-time: skipping $attribute_name"
continue
} else {
ns_log Notice "sla-resolution-time: showing $attribute_name"
}
# Calculate the "dereference" DynField value
set deref "substring(${deref_plpgsql_function}($attribute_name)::text for 100) as ${attribute_name}_deref"
if {"" == $deref} { set deref "substring($attribute_name::text for 100) as ${attribute_name}_deref" }
regsub -all {[^a-zA-Z0-9\ \-\.]} $pretty_name {} pretty_name
lappend header0 $pretty_name
lappend footer0 ""
lappend sla_footer ""
lappend derefs $deref
set var_name "\$${attribute_name}_deref"
lappend ticket_header $var_name
}
# ----------------------------------------------------------------
# Add the ticket resolution time per group
# First we have to find out if there are times logged for the
# specific group, then we can add the group to the list headers.
# ----------------------------------------------------------------
# find out the groups that do have resolution time in the system
set group_sql "
select g.*
from groups g
where g.group_id > 0
order by g.group_id
"
set cnt 0
set group_selects {}
db_foreach groups $group_sql {
incr cnt
lappend group_selects "sum(t.ticket_resolution_time_per_queue\[$cnt\]) as rtime_$cnt"
}
set group_sum_sql "
select [join $group_selects ",\n\t\t"]
from im_tickets t
where t.ticket_creation_date >= :start_date and
t.ticket_creation_date < :end_date
"
db_1row group_sum $group_sum_sql
# Calculate a list of groups for storing resolution times per group
set cnt 0
db_foreach groups $group_sql {
incr cnt
# Check if there has been some resolution time spent for in this group
if {![info exists rtime_$cnt]} { ad_return_complaint 1 "Error: didn't find 'rtime_$cnt'" }
set rtime [expr "\$rtime_$cnt"]
if {"" == $rtime} { set rtime 0.00 }
ns_log Notice "sla-resolution-time: cnt=$cnt, rtime=$rtime"
if {$rtime < 0.01} { continue }
lappend header0 $group_name
set var_name "group${group_id}_restime"
lappend ticket_header "\#align=right \[lc_numeric \$$var_name {} $locale \]"
set deref "t.ticket_resolution_time_per_queue\[$cnt\] as $var_name"
lappend derefs $deref
# Total Counters
lappend counters [list pretty_name "$group_name Total Sum" var "${var_name}_total_sum" reset 0 expr "\$$var_name+0"]
lappend counters [list pretty_name "$group_name Total Count" var "${var_name}_total_count" reset 0 expr "1"]
lappend footer0 "\#align=right \[lc_numeric \[expr round(100.0 * \$${var_name}_total_sum / \$${var_name}_total_count\) / 100.0\] {} $locale\]"
# Por SLA
lappend counters [list pretty_name "$group_name SLA Sum" var "${var_name}_sla_sum" reset "\$sla_id" expr "\$$var_name+0"]
lappend counters [list pretty_name "$group_name SLA Count" var "${var_name}_sla_count" reset "\$sla_id" expr "1"]
lappend sla_footer "\#align=right \[lc_numeric \[expr round(100.0 * \$${var_name}_sla_sum / \$${var_name}_sla_count\) / 100.0\] {} $locale\]"
}
# ----------------------------------------------------------------
# The entries in this list include <a HREF=...> tags
# in order to link the entries to the rest of the system (New!)
# ----------------------------------------------------------------
#
set report_def [list \
group_by company_id \
header $customer_header \
content [list \
group_by sla_id \
header $sla_header \
content [list \
group_by ticket_id \
header $ticket_header \
content {} \
footer {} \
] \
footer $sla_footer \
]\
footer {} \
]
# ------------------------------------------------------------
# Report SQL - This SQL statement defines the raw data
# that are to be shown.
set criteria [list]
if {0 != $customer_id && "" != $customer_id} {
lappend criteria "p.company_id = :customer_id"
}
if {0 != $ticket_type_id && "" != $ticket_type_id} {
lappend criteria "t.ticket_type_id in (select * from im_sub_categories(:ticket_type_id))"
}
set where_clause [join $criteria " and\n\t\t"]
if { ![empty_string_p $where_clause] } { set where_clause " and $where_clause" }
set report_sql "
select
o.*,
im_name_from_user_id(o.creation_user) as creation_user_name,
to_char(o.creation_date, :date_time_format) as creation_date_pretty,
t.*,
im_category_from_id(t.ticket_status_id) as ticket_status,
im_category_from_id(t.ticket_type_id) as ticket_type,
im_name_from_user_id(t.ticket_assignee_id) as ticket_assignee,
to_char(t.ticket_creation_date, :date_time_format) as ticket_creation_date_pretty,
to_char(t.ticket_reaction_date, :date_time_format) as ticket_reaction_date_pretty,
to_char(t.ticket_done_date, :date_time_format) as ticket_done_date_pretty,
to_char(t.ticket_reaction_date, :date_time_format) as ticket_reaction_date_pretty,
to_char(t.ticket_confirmation_date, :date_time_format) as ticket_confirmation_date_pretty,
to_char(t.ticket_signoff_date, :date_time_format) as ticket_signoff_date_pretty,
im_name_from_user_id(t.ticket_customer_contact_id) as ticket_customer_contact_name,
p.*,
substring(p.project_name for 30) as project_name_pretty,
g.*,
g.group_name as ticket_queue,
cust.*,
im_category_from_id(cust.company_type_id) as company_type,
sla_project.project_id as sla_id,
sla_project.project_nr as sla_nr,
sla_project.project_name as sla_name,
[join $derefs "\t,\n"]
from
acs_objects o,
im_projects p
LEFT OUTER JOIN im_companies cust ON (p.company_id = cust.company_id)
LEFT OUTER JOIN im_offices office ON (office.office_id = cust.main_office_id)
LEFT OUTER JOIN im_projects sla_project ON (p.parent_id = sla_project.project_id),
im_tickets t
LEFT OUTER JOIN persons p_contact ON (t.ticket_customer_contact_id = p_contact.person_id)
LEFT OUTER JOIN parties pa_contact ON (t.ticket_customer_contact_id = pa_contact.party_id)
LEFT OUTER JOIN groups g ON (t.ticket_queue_id = g.group_id)
where
t.ticket_id = o.object_id and
t.ticket_id = p.project_id and
t.ticket_creation_date >= :start_date and
t.ticket_creation_date < :end_date and
t.ticket_status_id not in (
[im_ticket_status_deleted],
[im_ticket_status_canceled]
)
$where_clause
order by
lower(cust.company_name),
lower(sla_project.project_name),
lower(im_name_from_user_id(o.creation_user)),
lower(p.project_nr)
"
# --------------------------------------------------------
# Write out HTTP header, considering CSV/MS-Excel formatting
im_report_write_http_headers -output_format $output_format
switch $output_format {
html {
ns_write "
[im_header]
[im_navbar]
<form>
<table cellspacing=10 cellpadding=0 border=0>
<tr valign=top>
<td>
<!-- 'Filters' - Show the Report parameters -->
<table cellspacing=2>
<tr class=rowtitle>
<td class=rowtitle colspan=2 align=center>Filters</td>
</tr>
<tr>
<td class=form-label>Level of Details</td>
<td class=form-widget>
[im_select -translate_p 0 level_of_detail $levels $level_of_detail]
</td>
</tr>
<tr>
<td><nobr>Start Date:</nobr></td>
<td><input type=text name=start_date value='$start_date'></td>
</tr>
<tr>
<td>End Date:</td>
<td><input type=text name=end_date value='$end_date'></td>
</tr>
<tr>
<td class=form-label>Ticket Type</td>
<td class=form-widget>
[im_category_select -include_empty_p 1 -include_empty_name [lang::message::lookup "" intranet-core.All "All"] "Intranet Ticket Type" ticket_type_id $ticket_type_id]
</td>
</tr>
<tr>
<td>[lang::message::lookup "" intranet-sla-management.Customer "Customer"]</td>
<td>[im_company_select -include_empty_name [lang::message::lookup "" intranet-core.All "All"] customer_id $customer_id]</td>
</tr>
<tr>
<td class=form-label>Format</td>
<td class=form-widget>
[im_report_output_format_select output_format "" $output_format]
</td>
</tr>
<tr>
<td</td>
<td><input type=submit value='Submit'></td>
</tr>
</table>
</td>
<td align=center>
<table cellspacing=2>
<tr class=rowtitle>
<td class=rowtitle align=center>
[lang::message::lookup "" intranet-sla-management.Ticket_Fields "Ticket Fields"]
</td>
</tr>
<tr>
<td>
<select name=show_dynfields size=6 multiple>
$dynfield_options
</select>
</td>
</tr>
</table>
</td>
<td align=center>
<table cellspacing=2>
<tr>
<td>$help_text</td>
</tr>
</table>
</td>
</tr>
</table>
</form>
<!-- Here starts the main report table -->
<table border=0 cellspacing=1 cellpadding=1>
"
}
printer {
ns_write "
<link rel=StyleSheet type='text/css' href='/intranet-reporting/printer-friendly.css' media=all>
<div class=\"fullwidth-list\">
<table border=0 cellspacing=1 cellpadding=1 rules=all>
<colgroup>
<col id=datecol>
<col id=hourcol>
<col id=datecol>
<col id=datecol>
<col id=hourcol>
<col id=hourcol>
<col id=hourcol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
</colgroup>
"
}
}
set footer_array_list [list]
set last_value_list [list]
im_report_render_row \
-output_format $output_format \
-row $header0 \
-row_class "rowtitle" \
-cell_class "rowtitle"
set counter 0
set class ""
db_foreach sql $report_sql {
# Select either "roweven" or "rowodd" from
# a "hash", depending on the value of "counter".
# You need explicite evaluation ("expre") in TCL
# to calculate arithmetic expressions.
set class $rowclass([expr $counter % 2])
im_report_display_footer \
-output_format $output_format \
-group_def $report_def \
-footer_array_list $footer_array_list \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-row_class $class \
-cell_class $class
im_report_update_counters -counters $counters
if {"" != $ticket_type} {
set category_key "intranet-core.[lang::util::suggest_key $ticket_type]"
set ticket_type [lang::message::lookup $locale $category_key $ticket_type]
}
if {"" != $company_type} {
set category_key "intranet-core.[lang::util::suggest_key $company_type]"
set company_type [lang::message::lookup $locale $category_key $company_type]
}
if {"Employees" == $ticket_queue} { set ticket_queue "" }
set last_value_list [im_report_render_header \
-output_format $output_format \
-group_def $report_def \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-row_class $class \
-cell_class $class
]
set footer_array_list [im_report_render_footer \
-output_format $output_format \
-group_def $report_def \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-row_class $class \
-cell_class $class
]
incr counter
}
im_report_display_footer \
-output_format $output_format \
-group_def $report_def \
-footer_array_list $footer_array_list \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-display_all_footers_p 1 \
-row_class $class \
-cell_class $class
# Calculate fields for totoal (footer0)
# which can be undefined.
set ticket_resolution_time_total_median 0.00
catch { set ticket_resolution_time_total_median [expr $ticket_resolution_time_total_sum / $ticket_resolution_time_total_count] }
im_report_render_row \
-output_format $output_format \
-row $footer0 \
-row_class $class \
-cell_class $class \
-upvar_level 1
ns_log Notice "report-tickets: $output_format"
# Write out the HTMl to close the main report table
# and write out the page footer.
#
switch $output_format {
html { ns_write "</table>[im_footer]\n" }
printer { ns_write "</table>\n</div>\n" }
cvs { }
}
# /packages/intranet-sencha-ticket-tracker/report-tickets.tcl
#
# Copyright (c) 2011 ]project-open[
#
# All rights reserved.
# Please see http://www.project-open.com/ for licensing.
ad_page_contract {
Show Resolution time per ticket
} {
{ start_date "" }
{ end_date "" }
{ level_of_detail:integer 3 }
{ customer_id:integer 0 }
{ ticket_type_id:integer 0 }
{ show_dynfields:multiple ""}
{ output_format "html" }
{ locale "es_ES" }
}
# ------------------------------------------------------------
# Security
#
set menu_label "reporting-helpdesk-sla-resolution-time"
set current_user_id [auth::require_login]
set read_p [db_string report_perms "
select im_object_permission_p(m.menu_id, :current_user_id, 'read')
from im_menus m
where m.label = :menu_label
" -default 'f']
# For testing - set manually
set read_p "t"
if {"t" ne $read_p } {
set message "You don't have the necessary permissions to view this page"
ad_return_complaint 1 "<li>$message"
ad_script_abort
}
set form_mode display
# set locale [lang::user::locale -user_id $current_user_id]
switch $locale {
en_US {
set number_format "999999999999.00"
}
default {
set number_format "999999999999,00"
}
}
# ------------------------------------------------------------
# Check Parameters
# ------------------------------------------------------------
# Defaults
set days_in_past 7
db_1row todays_date "
select
to_char(sysdate::date - :days_in_past::integer, 'YYYY') as todays_year,
to_char(sysdate::date - :days_in_past::integer, 'MM') as todays_month,
to_char(sysdate::date - :days_in_past::integer, 'DD') as todays_day
from dual
"
if {"" == $start_date} {
set start_date "$todays_year-$todays_month-01"
}
db_1row end_date "
select
to_char(to_date(:start_date, 'YYYY-MM-DD') + '2 month'::interval, 'YYYY') as end_year,
to_char(to_date(:start_date, 'YYYY-MM-DD') + '2 month'::interval, 'MM') as end_month,
to_char(to_date(:start_date, 'YYYY-MM-DD') + '2 month'::interval, 'DD') as end_day
from dual
"
if {"" == $end_date} {
set end_date "$end_year-$end_month-01"
}
if {![regexp {[0-9][0-9][0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]} $start_date]} {
ad_return_complaint 1 "Start Date doesn't have the right format.<br>
Current value: '$start_date'<br>
Expected format: 'YYYY-MM-DD'"
ad_script_abort
}
if {![regexp {[0-9][0-9][0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]} $end_date]} {
ad_return_complaint 1 "End Date doesn't have the right format.<br>
Current value: '$end_date'<br>
Expected format: 'YYYY-MM-DD'"
ad_script_abort
}
# Maxlevel is 3.
if {$level_of_detail > 3} { set level_of_detail 3 }
# ------------------------------------------------------------
# Page Title, Bread Crums and Help
#
set page_title "Ticket Resolution Time"
set context_bar [im_context_bar $page_title]
set help_text "
<strong>$page_title</strong><br>
The report shows the 'resolution time' per ticket and ticket queue
together with median values per SLA and for all selected tickets.<br>
The start- and end date act on the creation date of the ticket,
including start date but excluding end date.<br>
The report excludes tickets in the current status of 'canceled' and
'deleted'.
"
# ------------------------------------------------------------
# Default Values and Constants
set rowclass(0) "roweven"
set rowclass(1) "rowodd"
set currency_format "999,999,999.09"
set date_format "YYYY-MM-DD"
set date_time_format "YYYY-MM-DD HH24:MI"
set company_url "/intranet/companies/view"
set project_url "/intranet/projects/view"
set ticket_url "/intranet-helpdesk/new"
set invoice_url "/intranet-invoices/view"
set user_url "/intranet/users/view"
set this_url [export_vars -base "/intranet-sla-management/reports/sla-resolution-time" {start_date end_date} ]
# Level of Details
set levels {2 "Customer+SLA" 3 "All Details"}
# ------------------------------------------------------------
# Report Definition
#
# Reports are defined in a "declarative" style. The definition
# consists of a number of fields for header, lines and footer.
# Global Header Line
set header0 [list \
[lang::message::lookup "" intranet-sla-management.Ticket_Customer "Customer"] \
[lang::message::lookup "" intranet-sla-management.Ticket_SLA "SLA"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Customer_Contact "Customer<br>Contact"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Name "Ticket<br>Name"] \
[lang::message::lookup "" intranet-sla-management.Creation_User "Creation<br>User"] \
[lang::message::lookup "" intranet-sla-management.Ticket_Resolution_Time "Resolution<br>Time"] \
]
# Global Footer Line
set footer0 {
"$ticket_resolution_time_total_count"
""
""
""
""
"\#align=right \[lc_numeric \[expr {round(100.0 * \$ticket_resolution_time_total_median) / 100.0}\] {} \$locale\]"
}
set customer_header {
"\#colspan=99 <b><a href=[export_vars -base $company_url {{company_id $company_id}}]>$company_name</a></b>"
}
set sla_header {
""
"\#colspan=98 <b><a href=[export_vars -base $project_url {{project_id $sla_id}}]>$sla_name</a></b>"
}
set sla_footer {
"$ticket_resolution_time_sla_count"
"$sla_nr"
""
""
""
"\#align=right [lc_numeric [expr {round(100.0 * $ticket_resolution_time_sla_sum / $ticket_resolution_time_sla_count) / 100.0}] {} $locale]"
}
set ticket_header {
"$ticket_resolution_time_sla_count"
"$sla_nr"
"<a href=[export_vars -base $user_url {{user_id $ticket_customer_contact_id}}]>$ticket_customer_contact_name</a>"
"<a href=[export_vars -base $ticket_url {{ticket_id $ticket_id} form_mode}]>$project_nr - $project_name_pretty</a>"
"<a href=[export_vars -base $user_url {{user_id $creation_user}}]>$creation_user_name</a>"
"\#align=right \[lc_numeric $ticket_resolution_time {} $locale\]"
}
set counters [list]
# Counters for resolution time per SLA and total
lappend counters [list pretty_name "Solution Time SLA Sum" var ticket_resolution_time_sla_sum reset "\$sla_id" expr "\$ticket_resolution_time"]
lappend counters [list pretty_name "Solution Time SLA Count" var ticket_resolution_time_sla_count reset "\$sla_id" expr "1"]
lappend counters [list pretty_name "Solution Time Total Sum" var ticket_resolution_time_total_sum reset 0 expr "\$ticket_resolution_time"]
lappend counters [list pretty_name "Solution Time Total Count" var ticket_resolution_time_total_count reset 0 expr "1"]
set ticket_resolution_time_total_sum 0
set ticket_resolution_time_total_count 0
# ------------------------------------------------------------
# Add all Project and Company DynFields to list
set dynfield_sql "
select aa.attribute_name,
aa.pretty_name,
w.widget as tcl_widget,
w.widget_name as dynfield_widget,
w.deref_plpgsql_function
from im_dynfield_attributes a,
im_dynfield_widgets w,
acs_attributes aa
where a.widget_name = w.widget_name and
a.acs_attribute_id = aa.attribute_id and
aa.object_type = 'im_ticket' and
aa.attribute_name not like 'default%' and
aa.attribute_name not in (
-- Fields already hard coded in the report
'ticket_customer_contact_id'
)
order by
a.also_hard_coded_p DESC,
aa.object_type,
aa.sort_order
"
ns_log Notice "sla-resolution-time: show_dynfields=$show_dynfields"
set derefs [list "1 as one"]
set dynfield_options {}
db_foreach dynfield_attributes $dynfield_sql {
# Skip the DynField completely if the columns doesn't exist (Dynfield configuration errors)
if {![im_column_exists "im_tickets" $attribute_name]} { continue }
# Add the dynfield to the list of options
if {[lsearch $show_dynfields $attribute_name] > -1} { set selected "selected" } else { set selected "" }
append dynfield_options "\t\t<option value=$attribute_name $selected>$pretty_name</option>\n"
# Has the Dynfield been selected to be shown?
if {[lsearch $show_dynfields $attribute_name] < 0} {
ns_log Notice "sla-resolution-time: skipping $attribute_name"
continue
} else {
ns_log Notice "sla-resolution-time: showing $attribute_name"
}
# Calculate the "dereference" DynField value
set deref "substring(${deref_plpgsql_function}($attribute_name)::text for 100) as ${attribute_name}_deref"
if {"" == $deref} { set deref "substring($attribute_name::text for 100) as ${attribute_name}_deref" }
regsub -all {[^a-zA-Z0-9\ \-\.]} $pretty_name {} pretty_name
lappend header0 $pretty_name
lappend footer0 ""
lappend sla_footer ""
lappend derefs $deref
set var_name "\$${attribute_name}_deref"
lappend ticket_header $var_name
}
# ----------------------------------------------------------------
# Add the ticket resolution time per group
# First we have to find out if there are times logged for the
# specific group, then we can add the group to the list headers.
# ----------------------------------------------------------------
# find out the groups that do have resolution time in the system
set group_sql "
select g.*
from groups g
where g.group_id > 0
order by g.group_id
"
set cnt 0
set group_selects {}
db_foreach groups $group_sql {
incr cnt
lappend group_selects "sum(t.ticket_resolution_time_per_queue\[$cnt\]) as rtime_$cnt"
}
set group_sum_sql "
select [join $group_selects ",\n\t\t"]
from im_tickets t
where t.ticket_creation_date >= :start_date and
t.ticket_creation_date < :end_date
"
db_1row group_sum $group_sum_sql
# Calculate a list of groups for storing resolution times per group
set cnt 0
db_foreach groups $group_sql {
incr cnt
# Check if there has been some resolution time spent for in this group
if {![info exists rtime_$cnt]} { ad_return_complaint 1 "Error: didn't find 'rtime_$cnt'" }
set rtime [expr "\$rtime_$cnt"]
if {"" == $rtime} { set rtime 0.00 }
ns_log Notice "sla-resolution-time: cnt=$cnt, rtime=$rtime"
if {$rtime < 0.01} { continue }
lappend header0 $group_name
set var_name "group${group_id}_restime"
lappend ticket_header "\#align=right \[lc_numeric \$$var_name {} $locale \]"
set deref "t.ticket_resolution_time_per_queue\[$cnt\] as $var_name"
lappend derefs $deref
# Total Counters
lappend counters [list pretty_name "$group_name Total Sum" var "${var_name}_total_sum" reset 0 expr "\$$var_name+0"]
lappend counters [list pretty_name "$group_name Total Count" var "${var_name}_total_count" reset 0 expr "1"]
lappend footer0 "\#align=right \[lc_numeric \[expr round(100.0 * \$${var_name}_total_sum / \$${var_name}_total_count\) / 100.0\] {} $locale\]"
# Por SLA
lappend counters [list pretty_name "$group_name SLA Sum" var "${var_name}_sla_sum" reset "\$sla_id" expr "\$$var_name+0"]
lappend counters [list pretty_name "$group_name SLA Count" var "${var_name}_sla_count" reset "\$sla_id" expr "1"]
lappend sla_footer "\#align=right \[lc_numeric \[expr round(100.0 * \$${var_name}_sla_sum / \$${var_name}_sla_count\) / 100.0\] {} $locale\]"
}
# ----------------------------------------------------------------
# The entries in this list include <a HREF=...> tags
# in order to link the entries to the rest of the system (New!)
# ----------------------------------------------------------------
#
set report_def [list \
group_by company_id \
header $customer_header \
content [list \
group_by sla_id \
header $sla_header \
content [list \
group_by ticket_id \
header $ticket_header \
content {} \
footer {} \
] \
footer $sla_footer \
]\
footer {} \
]
# ------------------------------------------------------------
# Report SQL - This SQL statement defines the raw data
# that are to be shown.
set criteria [list]
if {0 != $customer_id && "" != $customer_id} {
lappend criteria "p.company_id = :customer_id"
}
if {0 != $ticket_type_id && "" != $ticket_type_id} {
lappend criteria "t.ticket_type_id in (select * from im_sub_categories(:ticket_type_id))"
}
set where_clause [join $criteria " and\n\t\t"]
if { $where_clause ne "" } { set where_clause " and $where_clause" }
set report_sql "
select
o.*,
im_name_from_user_id(o.creation_user) as creation_user_name,
to_char(o.creation_date, :date_time_format) as creation_date_pretty,
t.*,
im_category_from_id(t.ticket_status_id) as ticket_status,
im_category_from_id(t.ticket_type_id) as ticket_type,
im_name_from_user_id(t.ticket_assignee_id) as ticket_assignee,
to_char(t.ticket_creation_date, :date_time_format) as ticket_creation_date_pretty,
to_char(t.ticket_reaction_date, :date_time_format) as ticket_reaction_date_pretty,
to_char(t.ticket_done_date, :date_time_format) as ticket_done_date_pretty,
to_char(t.ticket_reaction_date, :date_time_format) as ticket_reaction_date_pretty,
to_char(t.ticket_confirmation_date, :date_time_format) as ticket_confirmation_date_pretty,
to_char(t.ticket_signoff_date, :date_time_format) as ticket_signoff_date_pretty,
im_name_from_user_id(t.ticket_customer_contact_id) as ticket_customer_contact_name,
p.*,
substring(p.project_name for 30) as project_name_pretty,
g.*,
g.group_name as ticket_queue,
cust.*,
im_category_from_id(cust.company_type_id) as company_type,
sla_project.project_id as sla_id,
sla_project.project_nr as sla_nr,
sla_project.project_name as sla_name,
[join $derefs "\t,\n"]
from
acs_objects o,
im_projects p
LEFT OUTER JOIN im_companies cust ON (p.company_id = cust.company_id)
LEFT OUTER JOIN im_offices office ON (office.office_id = cust.main_office_id)
LEFT OUTER JOIN im_projects sla_project ON (p.parent_id = sla_project.project_id),
im_tickets t
LEFT OUTER JOIN persons p_contact ON (t.ticket_customer_contact_id = p_contact.person_id)
LEFT OUTER JOIN parties pa_contact ON (t.ticket_customer_contact_id = pa_contact.party_id)
LEFT OUTER JOIN groups g ON (t.ticket_queue_id = g.group_id)
where
t.ticket_id = o.object_id and
t.ticket_id = p.project_id and
t.ticket_creation_date >= :start_date and
t.ticket_creation_date < :end_date and
t.ticket_status_id not in (
[im_ticket_status_deleted],
[im_ticket_status_canceled]
)
$where_clause
order by
lower(cust.company_name),
lower(sla_project.project_name),
lower(im_name_from_user_id(o.creation_user)),
lower(p.project_nr)
"
# --------------------------------------------------------
# Write out HTTP header, considering CSV/MS-Excel formatting
im_report_write_http_headers -output_format $output_format
switch $output_format {
html {
ns_write "
[im_header]
[im_navbar]
<form>
<table cellspacing=10 cellpadding=0 border=0>
<tr valign=top>
<td>
<!-- 'Filters' - Show the Report parameters -->
<table cellspacing=2>
<tr class=rowtitle>
<td class=rowtitle colspan=2 align=center>Filters</td>
</tr>
<tr>
<td class=form-label>Level of Details</td>
<td class=form-widget>
[im_select -translate_p 0 level_of_detail $levels $level_of_detail]
</td>
</tr>
<tr>
<td><nobr>Start Date:</nobr></td>
<td><input type=text name=start_date value='$start_date'></td>
</tr>
<tr>
<td>End Date:</td>
<td><input type=text name=end_date value='$end_date'></td>
</tr>
<tr>
<td class=form-label>Ticket Type</td>
<td class=form-widget>
[im_category_select -include_empty_p 1 -include_empty_name [lang::message::lookup "" intranet-core.All "All"] "Intranet Ticket Type" ticket_type_id $ticket_type_id]
</td>
</tr>
<tr>
<td>[lang::message::lookup "" intranet-sla-management.Customer "Customer"]</td>
<td>[im_company_select -include_empty_name [lang::message::lookup "" intranet-core.All "All"] customer_id $customer_id]</td>
</tr>
<tr>
<td class=form-label>Format</td>
<td class=form-widget>
[im_report_output_format_select output_format "" $output_format]
</td>
</tr>
<tr>
<td</td>
<td><input type=submit value='Submit'></td>
</tr>
</table>
</td>
<td align=center>
<table cellspacing=2>
<tr class=rowtitle>
<td class=rowtitle align=center>
[lang::message::lookup "" intranet-sla-management.Ticket_Fields "Ticket Fields"]
</td>
</tr>
<tr>
<td>
<select name=show_dynfields size=6 multiple>
$dynfield_options
</select>
</td>
</tr>
</table>
</td>
<td align=center>
<table cellspacing=2>
<tr>
<td>$help_text</td>
</tr>
</table>
</td>
</tr>
</table>
</form>
<!-- Here starts the main report table -->
<table border=0 cellspacing=1 cellpadding=1>
"
}
printer {
ns_write "
<link rel=StyleSheet type='text/css' href='/intranet-reporting/printer-friendly.css' media=all>
<div class=\"fullwidth-list\">
<table border=0 cellspacing=1 cellpadding=1 rules=all>
<colgroup>
<col id=datecol>
<col id=hourcol>
<col id=datecol>
<col id=datecol>
<col id=hourcol>
<col id=hourcol>
<col id=hourcol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
<col id=datecol>
</colgroup>
"
}
}
set footer_array_list [list]
set last_value_list [list]
im_report_render_row \
-output_format $output_format \
-row $header0 \
-row_class "rowtitle" \
-cell_class "rowtitle"
set counter 0
set class ""
db_foreach sql $report_sql {
# Select either "roweven" or "rowodd" from
# a "hash", depending on the value of "counter".
# You need explicite evaluation ("expre") in TCL
# to calculate arithmetic expressions.
set class $rowclass([expr {$counter % 2}])
im_report_display_footer \
-output_format $output_format \
-group_def $report_def \
-footer_array_list $footer_array_list \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-row_class $class \
-cell_class $class
im_report_update_counters -counters $counters
if {"" != $ticket_type} {
set category_key "intranet-core.[lang::util::suggest_key $ticket_type]"
set ticket_type [lang::message::lookup $locale $category_key $ticket_type]
}
if {"" != $company_type} {
set category_key "intranet-core.[lang::util::suggest_key $company_type]"
set company_type [lang::message::lookup $locale $category_key $company_type]
}
if {"Employees" == $ticket_queue} { set ticket_queue "" }
set last_value_list [im_report_render_header \
-output_format $output_format \
-group_def $report_def \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-row_class $class \
-cell_class $class
]
set footer_array_list [im_report_render_footer \
-output_format $output_format \
-group_def $report_def \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-row_class $class \
-cell_class $class
]
incr counter
}
im_report_display_footer \
-output_format $output_format \
-group_def $report_def \
-footer_array_list $footer_array_list \
-last_value_array_list $last_value_list \
-level_of_detail $level_of_detail \
-display_all_footers_p 1 \
-row_class $class \
-cell_class $class
# Calculate fields for totoal (footer0)
# which can be undefined.
set ticket_resolution_time_total_median 0.00
catch { set ticket_resolution_time_total_median [expr {$ticket_resolution_time_total_sum / $ticket_resolution_time_total_count}] }
im_report_render_row \
-output_format $output_format \
-row $footer0 \
-row_class $class \
-cell_class $class \
-upvar_level 1
ns_log Notice "report-tickets: $output_format"
# Write out the HTMl to close the main report table
# and write out the page footer.
#
switch $output_format {
html { ns_write "</table>[im_footer]\n" }
printer { ns_write "</table>\n</div>\n" }
cvs { }
}
......@@ -2,17 +2,17 @@
<form action="/intranet-sla-management/service-hours-save" method=POST>
<%= [export_vars -form {return_url sla_id}] %>
<table cellspacing=0 cellpadding=0>
<table cellspacing="0" cellpadding="0">
<tr class=rowtitle>
<td class=rowtitle><%= [lang::message::lookup "" intranet-sla-management.Day "Day"] %></td>
<multiple name=hours>
<td class=rowtitle align=center>@hours.hour@</td>
<td class=rowtitle align="center">@hours.hour@</td>
</multiple>
</tr>
@body_html;noquote@
<tr>
<td colspan=25>
<input type=submit value=#intranet-core.Submit#>
<td colspan="25">
<input type="submit" value="#intranet-core.Submit#">
</td>
</tr>
</table>
......
......@@ -18,7 +18,7 @@
# Defaults & Security
# ---------------------------------------------------------------
set current_user_id [ad_maybe_redirect_for_registration]
set current_user_id [auth::require_login]
if {"" == $return_url} { set return_url [im_url_with_query] }
set page_title [lang::message::lookup "" intranet-sla-management.Service_Hours "Service Hours"]
set context_bar [im_context_bar $page_title]
......@@ -61,7 +61,7 @@ for {set day 0} {$day < 7} {incr day} {
set line_html "<tr>\n"
append line_html "<td>[lindex $dow_list $day]</td>\n"
for {set h 0} {$h < 24} {incr h} {
set idx [expr $day*100 + $h]
set idx [expr {$day*100 + $h}]
set hh $h
if {[string length $hh] < 2} { set hh "0$hh" }
set hh "$hh:01"
......
......@@ -20,7 +20,7 @@ ad_page_contract {
# Defaults & Security
# ---------------------------------------------------------------
set current_user_id [ad_maybe_redirect_for_registration]
set current_user_id [auth::require_login]
set page_title [lang::message::lookup "" intranet-sla-management.Save_Service_Hours "Save Service Hours"]
set context_bar [im_context_bar $page_title]
set page_focus "im_header_form.keywords"
......@@ -64,7 +64,7 @@ foreach dow {0 1 2 3 4 5 6} {
set start_pretty $start
if {[string length $start_pretty] < 2} { set start_pretty "0$start" }
# The end time is the start of the next hour, so we have to add +1 to end
set end_pretty [expr $end + 1]
set end_pretty [expr {$end + 1}]
if {[string length $end_pretty] < 2} { set end_pretty "0$end_pretty" }
lappend service_hours [list "$start_pretty:00" "$end_pretty:00"]
......
......@@ -21,7 +21,7 @@ ad_page_contract {
# ---------------------------------------------------------------
set user_id [ad_maybe_redirect_for_registration]
set user_id [auth::require_login]
if {"" == $param} { ad_returnredirect $return_url }
switch $action {
......
......@@ -23,7 +23,7 @@
# Defaults & Security
# ---------------------------------------------------------------
set current_user_id [ad_maybe_redirect_for_registration]
set current_user_id [auth::require_login]
set add_reports_p [im_permission $current_user_id "add_reports"]
set view_reports_all_p [im_permission $current_user_id "view_reports_all"]
......@@ -149,7 +149,7 @@ set body_html ""
set old_param_id ""
set param_cnt 0
set indicator_cnt 0
set colspan [expr [llength $dynfield_attributes] + 2]
set colspan [expr {[llength $dynfield_attributes] + 2}]
# Read the results into a multirow because
# the "evaluate" needs to alloc an additional DB connection
......@@ -190,7 +190,7 @@ template::multirow foreach param_indicators {
}
# if {[regexp {^([0-9]*)\.([0-9][0-9])} $result match body fraction]} { set result "$body.$fraction" }
if {[string is double $result]} { set result [expr round(100.0 * $result) / 100.0] }
if {[string is double $result]} { set result [expr {round(100.0 * $result) / 100.0}] }
set diagram_html [im_indicator_horizontal_bar \
-name $report_name \
......@@ -220,7 +220,7 @@ template::multirow foreach param_indicators {
if {!$add_reports_p} { set edit_html "" }
set row_html ""
append row_html "<tr $bgcolor([expr $indicator_cnt % 2])>\n"
append row_html "<tr $bgcolor([expr {$indicator_cnt % 2}])>\n"
append row_html "<td>&nbsp;</td>\n"
# append row_html "<td><input type=checkbox name=indicator value=$indicator_id></input></td>\n"
set indicator_url [export_vars -base "/intranet-reporting-indicators/view" {indicator_id}]
......
......@@ -23,7 +23,7 @@ if {![info exists object_id]} {
# This portlet only makes sense in SLAs...
if {![info exists return_url] || "" == $return_url} { set return_url [im_url_with_query] }
set current_user_id [ad_maybe_redirect_for_registration]
set current_user_id [auth::require_login]
set new_sla_parameter_url [export_vars -base "/intranet-sla-management/new" {object_id return_url}]
# Check the permissions
......
......@@ -23,7 +23,7 @@ ad_page_contract {
# Defaults & Security
# ---------------------------------------------------------------
set current_user_id [ad_maybe_redirect_for_registration]
set current_user_id [auth::require_login]
set sla_id $project_id
im_project_permissions $current_user_id $project_id sla_view sla_read sla_write sla_admin
......
......@@ -18,7 +18,7 @@
<td><%= [im_category_select "Intranet Ticket Status" ticket_severity_id ""] %></td>
<td><%= [im_category_select "Intranet Ticket Priority" ticket_prio_id ""] %></td>
</tr>
<tr><td colspan=3><input type=submit value='@create_new_entry_msg@'></td></tr>
<tr><td colspan="3"><input type="submit" value='@create_new_entry_msg@'></td></tr>
</table>
</form>
......
......@@ -18,7 +18,7 @@
# Defaults & Security
# ---------------------------------------------------------------
set current_user_id [ad_maybe_redirect_for_registration]
set current_user_id [auth::require_login]
if {"" == $return_url} { set return_url [im_url_with_query] }
set page_title [lang::message::lookup "" intranet-sla-management.Ticket_Priority "Ticket Priority"]
set context_bar [im_context_bar $page_title]
......
......@@ -21,7 +21,7 @@ ad_page_contract {
# Defaults & Security
# ---------------------------------------------------------------
set current_user_id [ad_maybe_redirect_for_registration]
set current_user_id [auth::require_login]
set sla_id $project_id
im_project_permissions $current_user_id $project_id sla_view sla_read sla_write sla_admin
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment