Commit 8710df3a authored by Frank Bergmann's avatar Frank Bergmann

Initial Import

parents
<?xml version="1.0"?>
<!-- Generated by the OpenACS Package Manager -->
<package key="oryx-ts-extensions" url="http://www.oryx-consulting.com/po/apm/oryx-ts-extensions-0.9.0.apm" type="apm_application">
<package-name>]project-open[ Timesheet extensions by Oryx Consulting</package-name>
<pretty-plural>]project-open[ Timesheet extensions by Oryx Consulting</pretty-plural>
<initial-install-p>f</initial-install-p>
<singleton-p>t</singleton-p>
<auto-mount>oryx-ts-extensions</auto-mount>
<version name="0.9.0" url="http://www.oryx-consulting.com/po/apm/oryx-ts-extensions-0.9.0.apm">
<owner url="mailto:b.dewolf@oryx-consulting.com">Bruno De Wolf</owner>
<release-date>2007-03-08</release-date>
<vendor url="http://www.oryx-consulting.com">Oryx Consulting</vendor>
<provides url="oryx-ts-extensions" version="0.9.0"/>
<requires url="intranet-reporting" version="3.1.2.0.0"/>
<callbacks>
</callbacks>
<parameters>
<parameter datatype="string" min_n_values="1" max_n_values="1" name="htmldoc-path" default="/usr/bin/htmldoc" description="Name of the htmldoc executable"/>
<parameter datatype="number" min_n_values="1" max_n_values="1" name="report-title" default="Oryx Consulting S.A." description="Title of the report"/>
</parameters>
</version>
</package>
---------------------------------------------------------
-- Timesheet Reports
--
create or replace function inline_0 ()
returns integer as '
declare
-- Menu IDs
v_menu integer;
v_main_menu integer;
-- Groups
v_employees integer;
v_accounting integer;
v_senman integer;
v_customers integer;
v_freelancers integer;
v_proman integer;
v_admins integer;
v_reg_users integer;
BEGIN
select group_id into v_admins from groups where group_name = ''P/O Admins'';
select group_id into v_senman from groups where group_name = ''Senior Managers'';
select group_id into v_proman from groups where group_name = ''Project Managers'';
select group_id into v_accounting from groups where group_name = ''Accounting'';
select group_id into v_employees from groups where group_name = ''Employees'';
select group_id into v_customers from groups where group_name = ''Customers'';
select group_id into v_freelancers from groups where group_name = ''Freelancers'';
select group_id into v_reg_users from groups where group_name = ''Registered Users'';
select menu_id
into v_main_menu
from im_menus
where label=''reporting-timesheet'';
v_menu := im_menu__new (
null, -- p_menu_id
''acs_object'', -- object_type
now(), -- creation_date
null, -- creation_user
null, -- creation_ip
null, -- context_id
''oryx-ts-extensions'', -- package_name
''oryx-ts-printing'', -- label
''Printable timesheets'', -- name
''/oryx-ts-extensions/oryx-ts-printreport'', -- url
120, -- sort_order
v_main_menu, -- parent_menu_id
null -- p_visible_tcl
);
PERFORM acs_permission__grant_permission(v_menu, v_admins, ''read'');
PERFORM acs_permission__grant_permission(v_menu, v_senman, ''read'');
PERFORM acs_permission__grant_permission(v_menu, v_proman, ''read'');
PERFORM acs_permission__grant_permission(v_menu, v_accounting, ''read'');
PERFORM acs_permission__grant_permission(v_menu, v_employees, ''read'');
return 0;
end;' language 'plpgsql';
select inline_0 ();
drop function inline_0 ();
select im_menu__del_module('oryx-ts-extensions');
# packages/oryx-ts-extensions/www/tsdetail.tcl
# This code is a modified version of
# /packages/intranet-reporting/www/timesheet-companies-projects.tcl
# The code is based on ArsDigita ACS 3.4
# and code from Frank Bergmann (frank.bergmann@project-open.com)
# Modifications by: Bruno De Wolf (b.dewolf@oryx-consulting.com)
ad_page_contract {
testing reports
@param start_year Year to start the report
@param start_unit Month or week to start within the start_year
@param truncate_note_length Truncate (ellipsis) the note field
to the given number of characters. 0 indicates no
truncation.
} {
{ start_date "" }
{ end_date "" }
{ level_of_detail 2 }
{ truncate_note_length 80}
{ output_format "html" }
project_id:integer,optional
task_id:integer,optional
company_id:integer,optional
user_id:integer,optional
}
# ------------------------------------------------------------
# Security
# Label: Provides the security context for this report
# because it identifies unquely the report's Menu and
# its permissions.
set menu_label "oryx-ts-printing"
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']
if {![string equal "t" $read_p]} {
ad_return_complaint 1 "
[lang::message::lookup "" intranet-reporting.You_dont_have_permissions "You don't have the necessary permissions to view this page"]"
return
}
# Check that Start & End-Date have correct format
if {"" != $start_date && ![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'"
}
if {"" != $end_date && ![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'"
}
set page_title "Timesheet Report"
set context_bar [im_context_bar $page_title]
set context ""
# ------------------------------------------------------------
# Defaults
set rowclass(0) "roweven"
set rowclass(1) "rowodd"
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"
}
# Maxlevel is 4. Normalize in order to show the right drop-down element
if {$level_of_detail > 4} { set level_of_detail 4 }
db_1row end_date "
select
to_char(to_date(:start_date, 'YYYY-MM-DD') + 31::integer, 'YYYY') as end_year,
to_char(to_date(:start_date, 'YYYY-MM-DD') + 31::integer, 'MM') as end_month,
to_char(to_date(:start_date, 'YYYY-MM-DD') + 31::integer, 'DD') as end_day
from dual
"
if {"" == $end_date} {
set end_date "$end_year-$end_month-01"
}
set company_url "/intranet/companies/view?company_id="
set project_url "/oryx-ts-extensions/tsdetail?project_id="
set user_url "/oryx-ts-exenstions/tsdetail?user_id="
set this_url [export_vars -base "/oryx-ts-extensions/timesheet-customer-project" {start_date end_date} ]
set detail_url [export_vars -base "/oryx-ts-extensions/tsdetail" {start_date end_date} ]
# ------------------------------------------------------------
# Conditional SQL Where-Clause
#
set criteria [list]
if {[info exists company_id]} {
lappend criteria "p.company_id = :company_id"
}
if {[info exists user_id]} {
lappend criteria "h.user_id = :user_id"
}
if {[info exists task_id]} {
lappend criteria "h.project_id = :task_id"
}
# Select project & subprojects
if {[info exists project_id]} {
lappend criteria "p.project_id in (
select
p.project_id
from
im_projects p,
im_projects parent_p
where
parent_p.project_id = :project_id
and p.tree_sortkey between parent_p.tree_sortkey and tree_right(parent_p.tree_sortkey)
)"
}
set where_clause [join $criteria " and\n "]
if { ![empty_string_p $where_clause] } {
set where_clause " and $where_clause"
}
# ------------------------------------------------------------
# Define the report - SQL, counters, headers and footers
#
set inner_sql "
select
h.day::date as date,
h.note,
to_char(h.day, 'J')::integer - to_char(to_date(:start_date, 'YYYY-MM-DD'), 'J')::integer as date_diff,
h.user_id,
p.project_id,
p.company_id,
h.hours,
h.billing_rate
from
im_hours h,
im_projects p,
cc_users u
where
h.project_id = p.project_id
and h.user_id = u.user_id
and h.day >= to_date(:start_date, 'YYYY-MM-DD')
and h.day < to_date(:end_date, 'YYYY-MM-DD')
$where_clause
"
set sql "
select
to_char(s.date, 'YYYY-MM-DD') as date,
s.date_diff,
s.note,
u.user_id,
u.first_names || ' ' || u.last_name as user_name,
p.project_id,
p.project_nr,
p.project_name,
c.company_id,
c.company_path as company_nr,
c.company_name,
to_char(s.hours, '999,999.9') as hours,
to_char(s.billing_rate, '999,999.9') as billing_rate
from
($inner_sql) s,
im_companies c,
im_projects p,
cc_users u
where
s.user_id = u.user_id
and s.company_id = c.company_id
and s.project_id = p.project_id
order by
s.company_id,
p.project_id,
u.user_id,
s.date
"
set report_def [list \
group_by company_nr \
header {
"\#colspan=99 <a href=$this_url&company_id=$company_id&level_of_detail=4 target=_blank><img src=/intranet/images/plus_9.gif border=0></a>
<b><a href=$company_url$company_id>$company_name</a></b>"
} \
content [list \
group_by project_nr \
header {
$company_nr
"\#colspan=99 <b><a href=$detail_url&project_id=$project_id&level_of_detail=4 target=_blank>$project_name</a></b>"
} \
content [list \
group_by user_id \
header {
$company_nr
$project_nr
"\#colspan=99 <b><a href=$detail_url&project_id=$project_id&user_id=$user_id&level_of_detail=4 target=_blank>$user_name</a></b>"
} \
content [list \
header {
$company_nr
$project_nr
$user_name
$date
$hours
$billing_rate
$note
} \
content {} \
] \
footer {
$company_nr
$project_nr
$user_name
""
"<i>$hours_user_subtotal</i>"
""
""
} \
] \
footer {
$company_nr
$project_nr
""
""
"<b>$hours_project_subtotal</b>"
""
""
} \
] \
footer {"" "" "" "" "" "" ""} \
]
# Global header/footer
set header0 {"Customer" "Project" "User" "Date" Hours Rate Note}
set footer0 {"" "" "" "" "" "" ""}
set hours_user_counter [list \
pretty_name Hours \
var hours_user_subtotal \
reset \$user_id \
expr \$hours
]
set hours_project_counter [list \
pretty_name Hours \
var hours_project_subtotal \
reset \$project_id \
expr \$hours
]
set hours_customer_counter [list \
pretty_name Hours \
var hours_customer_subtotal \
reset \$company_id \
expr \$hours
]
set counters [list \
$hours_user_counter \
$hours_project_counter \
$hours_customer_counter \
]
# ------------------------------------------------------------
# Constants
#
set start_years {2000 2000 2001 2001 2002 2002 2003 2003 2004 2004 2005 2005 2006 2006}
set start_months {01 Jan 02 Feb 03 Mar 04 Apr 05 May 06 Jun 07 Jul 08 Aug 09 Sep 10 Oct 11 Nov 12 Dec}
set start_weeks {01 1 02 2 03 3 04 4 05 5 06 6 07 7 08 8 09 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27 28 28 29 29 30 30 31 31 32 32 33 33 34 34 35 35 36 36 37 37 38 38 39 39 40 40 41 41 42 42 43 43 44 44 45 45 46 46 47 47 48 48 49 49 50 50 51 51 52 52}
set start_days {01 1 02 2 03 3 04 4 05 5 06 6 07 7 08 8 09 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27 28 28 29 29 30 30 31 31}
set levels {1 "Customer Only" 2 "Customer+Project" 3 "Customer+Project+User" 4 "All Details"}
set truncate_note_options {0 "Full Length" 80 "Standard (80)" 20 "Short (20)"}
# ------------------------------------------------------------
# Start formatting the page
#
set report_options_html ""
if {$level_of_detail > 3} {
append report_options_html "
<tr>
<td class=form-label>Size of Note Field</td>
<td class=form-widget>
[im_select -translate_p 0 truncate_note_length $truncate_note_options $truncate_note_length]
</td>
</tr>
"
}
if {[info exists project_id]} {
append report_options_html "
<tr>
<td class=form-label></td>
<td class=form-widget>
<input type=hidden name=project_id value=\"$project_id\">
</td>
</tr>
"
}
if {[info exists task_id]} {
append report_options_html "
<tr>
<td class=form-label></td>
<td class=form-widget>
<input type=hidden name=task_id value=\"$task_id\">
</td>
</tr>
"
}
# ------------------------------------------------------------
# Start Formatting the HTML Page Contents
# 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 $page_title]
[im_navbar]
<form>
<table border=0 cellspacing=1 cellpadding=1>
<tr valign=top><td>
<table border=0 cellspacing=1 cellpadding=1>
<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 class=form-label>Start Date</td>
<td class=form-widget>
<input type=textfield name=start_date value=$start_date>
</td>
</tr>
<tr>
<td class=form-label>End Date</td>
<td class=form-widget>
<input type=textfield name=end_date value=$end_date>
</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 class=form-label></td>
<td class=form-widget><input type=submit value=Submit></td>
</tr>
</table>
</td><td>
<table border=0 cellspacing=1 cellpadding=1>
$report_options_html
</table>
</td></tr>
</table>
</form>
<table border=0 cellspacing=1 cellpadding=1>\n"
}
}
im_report_render_row \
-output_format $output_format \
-row $header0 \
-row_class "rowtitle" \
-cell_class "rowtitle"
set footer_array_list [list]
set last_value_list [list]
set class "rowodd"
db_foreach sql $sql {
if {[string length $note] > $truncate_note_length} {
set note "[string range $note 0 $truncate_note_length] ..."
}
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
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
]
}
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
im_report_render_row \
-output_format $output_format \
-row $footer0 \
-row_class $class \
-cell_class $class
# Write out the HTMl to close the main report table
# and write out the page footer.
#
switch $output_format {
html { ns_write "</table>\n[im_footer]\n"}
}
# packages/oryx-ts-extensions/www/tsdetail.tcl
# Author: Bruno De Wolf (b.dewolf@oryx-consulting.com)
# The code is based on ArsDigita ACS 3.4
# and code from Frank Bergmann (frank.bergmann@project-open.com)
ad_page_contract {
testing reports
@param start_year Year to start the report
@param start_unit Month or week to start within the start_year
@param truncate_note_length Truncate (ellipsis) the note field
to the given number of characters. 0 indicates no
truncation.
} {
{ start_date "" }
{ end_date "" }
{ level_of_detail 2 }
{ truncate_note_length 80}
{ output_format "html" }
project_id:integer,optional
task_id:integer,optional
company_id:integer,optional
user_id:integer,optional
}
# ------------------------------------------------------------
# Security
# Label: Provides the security context for this report
# because it identifies unquely the report's Menu and
# its permissions.
set menu_label "oryx-ts-printing"
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']
if {![string equal "t" $read_p]} {
ad_return_complaint 1 "
[lang::message::lookup "" intranet-reporting.You_dont_have_permissions "You don't have the necessary permissions to view this page"]"
return
}
# Check that Start & End-Date have correct format
if {"" != $start_date && ![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'"
}
if {"" != $end_date && ![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'"
}
set page_title "Timesheet Report"
set context_bar [im_context_bar $page_title]
set context ""
# ------------------------------------------------------------
# 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"
}
# Maxlevel is 4. Normalize in order to show the right drop-down element
if {$level_of_detail > 4} { set level_of_detail 4 }
db_1row end_date "
select
to_char(to_date(:start_date, 'YYYY-MM-DD') + 31::integer, 'YYYY') as end_year,
to_char(to_date(:start_date, 'YYYY-MM-DD') + 31::integer, 'MM') as end_month,
to_char(to_date(:start_date, 'YYYY-MM-DD') + 31::integer, 'DD') as end_day
from dual
"
if {"" == $end_date} {
set end_date "$end_year-$end_month-01"
}
set package_id 0
set package_key "oryx-ts-extensions"
db_1row get_package_id " select min(package_id) as package_id from apm_packages where package_key = :package_key"
set htmldoc_path [ad_parameter -package_id $package_id htmldoc-path "" "/usr/local/bin/htmldoc"]
set rep_title [ad_parameter -package_id $package_id report-title "" "Your company name"]
# ------------------------------------------------------------
# Conditional SQL Where-Clause
#
set criteria [list]
if {[info exists company_id]} {
lappend criteria "p.company_id = :company_id"
}
if {[info exists user_id]} {
lappend criteria "h.user_id = :user_id"
}
if {[info exists task_id]} {
lappend criteria "h.project_id = :task_id"
}
# Select project & subprojects
if {[info exists project_id]} {
lappend criteria "p.project_id in (
select
p.project_id
from
im_projects p,
im_projects parent_p
where
parent_p.project_id = :project_id
and p.tree_sortkey between parent_p.tree_sortkey and tree_right(parent_p.tree_sortkey)
)"
}
set where_clause [join $criteria " and\n "]
if { ![empty_string_p $where_clause] } {
set where_clause " and $where_clause"
}
# ------------------------------------------------------------
# Define the report - SQL, counters, headers and footers
#
set inner_sql "
select
h.day::date as date,
h.note,
to_char(h.day, 'J')::integer - to_char(to_date(:start_date, 'YYYY-MM-DD'), 'J')::integer as date_diff,
h.user_id,
p.project_id,
p.company_id,
h.hours,
h.billing_rate,
t.task_id,
t.task_name
from
im_hours h,
im_projects p,
im_timesheet_tasks t,
cc_users u
where
h.project_id = p.project_id
and h.timesheet_task_id = t.task_id
and h.user_id = u.user_id
and h.day >= to_date(:start_date, 'YYYY-MM-DD')
and h.day < to_date(:end_date, 'YYYY-MM-DD')
$where_clause
"
set sql "
select
to_char(s.date, 'YYYY-MM-DD') as date,
s.date_diff,
s.note,
s.task_id,
s.task_name,
u.user_id,
u.first_names || ' ' || u.last_name as user_name,
p.project_id,
p.project_nr,
p.project_name,
c.company_id,
c.company_path as company_nr,
c.company_name,
to_char(s.hours, '999,999') as hours,
to_char(s.billing_rate, '999,999.9') as billing_rate
from
($inner_sql) s,
im_companies c,
im_projects p,
cc_users u
where
s.user_id = u.user_id
and s.company_id = c.company_id
and s.project_id = p.project_id
order by
s.company_id,
p.project_id,
u.user_id,
s.task_id,
s.date
"
append timesheet_as_html " <html>
<!-- MEDIA LANDSCAPE YES -->
<body>
<table width=90%>
<tr><td><h4>$rep_title</h4></td><td align=left>Timesheet</td></tr>
</table>"
append timesheet_table "<table border=1> <tr> <td>&nbsp;</td> <td>&nbsp;</td>
<td>1</td> <td>2</td> <td>3</td> <td>4</td> <td>5</td>
<td>6</td> <td>7</td> <td>8</td> <td>9</td> <td>10</td>
<td>11</td> <td>12</td> <td>13</td> <td>14</td> <td>15</td>
<td>16</td> <td>17</td> <td>18</td> <td>19</td> <td>20</td>
<td>21</td> <td>22</td> <td>23</td> <td>24</td> <td>25</td>
<td>26</td> <td>27</td> <td>28</td> <td>29</td> <td>30</td>
<td>31</td> "
set ts_line {}
set old_user ""
set old_task ""
set old_daynum 31
set old_monthnum 0
set line_total "Total"
set grand_total 0
set n_lines 0
db_foreach ts_line $sql {
if {"0"==[string range $date 8 8]} {
set daynum [string range $date 9 9]
} else {
set daynum [string range $date 8 9]
}
if {"0"==[string range $date 5 5]} {
set monthnum [string range $date 6 6]
} else {
set monthnum [string range $date 5 6]
}
if {$old_user != $user_id || $old_task != $task_id || $monthnum !=$old_monthnum} {
# close the previous line and start a new one
for {set i $old_daynum} {$i < 31} {incr i} {
append timesheet_table "<td>&nbsp;</td>"
}
append timesheet_table "<td>$line_total</td>"
set old_daynum 0
set line_total 0
incr n_lines
append timesheet_table "</tr><tr>"
if {$old_user == $user_id} {
append timesheet_table "<td>&nbsp;</td>"
} else {
append timesheet_table "<td>$user_name</td>"
}
append timesheet_table "<td>$task_name</td>"
}
# output hours in the right column
for {set i $old_daynum} {$i < $daynum-1} {incr i} {
append timesheet_table "<td>&nbsp;</td>"
}
append timesheet_table "<td>$hours</td>"
# prepare the next iteration
set line_total [expr {$line_total + $hours}]
set grand_total [expr {$grand_total + $hours}]
set old_user $user_id
set old_task $task_id
set old_daynum $daynum
set old_monthnum $monthnum
}
# close the last line
for {set i $old_daynum} {$i < 31} {incr i} {
append timesheet_table "<td>&nbsp;</td>"
}
append timesheet_table "<td>$line_total</td></tr>"
for {set i $n_lines} {$i < 10} {incr i} {
append timesheet_table "<tr>"
for {set j 0} {$j < 34} {incr j} {
append timesheet_table "<td>&nbsp;</td>"
}
append timesheet_table "</tr>"
}
append timesheet_table "</table>"
append timesheet_as_html "<p><b>Customer:</b> $company_name</p>"
append timesheet_as_html "<p><b>Project:</b> $project_name</p>"
append timesheet_as_html "<p><b>Period:</b> $start_date to $end_date</p>"
append timesheet_as_html $timesheet_table
append timesheet_as_html "Total: $grand_total hours<br>"
append timesheet_as_html "<p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>"
append timesheet_as_html "<table><tr><td><b>Customer's signature:</b></td><td> ...................</td></tr>"
append timesheet_as_html "<tr><td>&nbsp;</td></tr>"
append timesheet_as_html "<tr><td><b>Date:</b></td><td> ...................</td></tr></table>"
append timesheet_as_html "</body></html> "
#generate the PDF output
set file_name_pdf [ns_tmpnam]
append file_name_pdf ".pdf"
if {[catch {exec echo \ $timesheet_as_html\ | $htmldoc_path --webpage --quiet -f $file_name_pdf -} result]} {
#Do nothing
}
ns_returnfile 200 application/pdf $file_name_pdf
ad_script_abort
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