View Issue Details

IDProjectCategoryView StatusLast Update
0007932mantisbttime trackingpublic2016-06-12 00:42
Reportervboctor Assigned Tovboctor  
PrioritynormalSeverityfeatureReproducibilityhave not tried
Status closedResolutionfixed 
Product Version1.2.19 
Target Version1.3.0-rc.2Fixed in Version1.3.0-rc.2 
Summary0007932: Implement CSV and Excel export for billing report
Description

It would be useful to provide a csv export of the billing report.

Tagsmantishub, patch
Attached Files
billing_export.patch (1,660 bytes)   
--- C:/xampp/virtual/bugs.prouse.org.orig/billing_inc.php	Thu Dec 20 16:01:11 2007
+++ C:/xampp/virtual/bugs.prouse.org/billing_inc.php	Fri Dec 21 12:12:25 2007
@@ -142,6 +142,25 @@
 	$t_prev_id = -1;
 ?>
 <br />
+<table class="width100" cellpadding="2">
+<tbody><tr>
+<?php
+  # Excel export
+  #$f_bug_array stores the number of the selected rows
+  #$t_bug_arr_sort is used for displaying
+  #$f_export is a string for the word and excel pages
+
+  $t_icon_path = config_get( 'icon_path' );
+  $t_excel_cost = $t_cost_col ? "&amp;bugnote_cost=".$f_bugnote_cost : "";
+?>
+
+<tr>
+  <td>
+    <a href="billing_excel.php?from=<?=$t_from?>&amp;to=<?=$t_to?><?=$t_excel_cost?>" title="Excel 2000"><img src="<?=$t_icon_path?>fileicons/xls.gif" border="0" align="absmiddle" alt="Excel" /></a>
+  <td>
+</tr>
+</tbody></table>
+<br />
 <table border="0" class="width100" cellspacing="0">
 <tr class="row-category-history">
 	<td class="small-caption">
@@ -159,9 +178,13 @@
 </tr>
 <?php
 	$t_sum_in_minutes = 0;
+	$t_sum_cost = 0;
 
 	foreach ( $t_bugnote_stats as $t_item ) {
 		$t_sum_in_minutes += $t_item['sum_time_tracking'];
+		if ($t_cost_col) {
+		  $t_sum_cost += $t_item['cost'];
+		}
 
 		$t_item['sum_time_tracking'] = db_minutes_to_hhmm( $t_item['sum_time_tracking'] );
 		if ( $t_item['bug_id'] != $t_prev_id) {
@@ -192,6 +215,11 @@
 	<td class="small-caption">
 		<?php echo db_minutes_to_hhmm( $t_sum_in_minutes ); ?>
 	</td>
+<?php if ($t_cost_col) { ?>
+  <td>
+    <?php echo string_attribute( number_format( $t_sum_cost, 2 ) ); ?>
+  </td>
+<?php } ?>
 </tr>
 </table>
 <?php } # end if ?>
billing_export.patch (1,660 bytes)   
billing_inc.php (7,410 bytes)   
<?php
# Mantis - a php based bugtracking system

# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
# Copyright (C) 2002 - 2007  Mantis Team   - mantisbt-dev@lists.sourceforge.net

# Mantis is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# Mantis is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mantis.  If not, see <http://www.gnu.org/licenses/>.

	# --------------------------------------------------------
	# $Id: billing_inc.php,v 1.14.2.1 2007-10-13 22:32:29 giallu Exp $
	# --------------------------------------------------------
?>
<?php
	# This include file prints out the bug bugnote_stats

	# $f_bug_id must already be defined
?>
<?php
	$t_core_path = config_get( 'core_path' );

	require_once( $t_core_path.'bugnote_api.php' );
?>
<?php
	if ( ! config_get('time_tracking_enabled') )
		return;
?>

<a name="bugnotestats" id="bugnotestats" /><br />

<?php 
	collapse_open( 'bugnotestats' );
?>

<table class="width100" cellspacing="0">
<tr>
	<td class="form-title" colspan="4">
		<?php collapse_icon( 'bugnotestats' );
		echo lang_get( 'time_tracking' ) ?>
	</td>
</tr>
</table>
<?php
	collapse_closed( 'bugnotestats' );

	$t_today = date( "d:m:Y" );
	$t_date_submitted = isset( $t_bug ) ? date( "d:m:Y", $t_bug->date_submitted ) : $t_today;

	$t_bugnote_stats_from_def = $t_date_submitted;
	$t_bugnote_stats_from_def_ar = explode ( ":", $t_bugnote_stats_from_def );
	$t_bugnote_stats_from_def_d = $t_bugnote_stats_from_def_ar[0];
	$t_bugnote_stats_from_def_m = $t_bugnote_stats_from_def_ar[1];
	$t_bugnote_stats_from_def_y = $t_bugnote_stats_from_def_ar[2];

	$t_bugnote_stats_from_d = gpc_get_int('start_day', $t_bugnote_stats_from_def_d);
	$t_bugnote_stats_from_m = gpc_get_int('start_month', $t_bugnote_stats_from_def_m);
	$t_bugnote_stats_from_y = gpc_get_int('start_year', $t_bugnote_stats_from_def_y);

	$t_bugnote_stats_to_def = $t_today;
	$t_bugnote_stats_to_def_ar = explode ( ":", $t_bugnote_stats_to_def );
	$t_bugnote_stats_to_def_d = $t_bugnote_stats_to_def_ar[0];
	$t_bugnote_stats_to_def_m = $t_bugnote_stats_to_def_ar[1];
	$t_bugnote_stats_to_def_y = $t_bugnote_stats_to_def_ar[2];

	$t_bugnote_stats_to_d = gpc_get_int('end_day', $t_bugnote_stats_to_def_d);
	$t_bugnote_stats_to_m = gpc_get_int('end_month', $t_bugnote_stats_to_def_m);
	$t_bugnote_stats_to_y = gpc_get_int('end_year', $t_bugnote_stats_to_def_y);

	$f_get_bugnote_stats_button = gpc_get_string('get_bugnote_stats_button', '');
	$f_bugnote_cost = gpc_get_int( 'bugnote_cost', '' );
	$f_project_id = helper_get_current_project();

	if ( ON == config_get( 'time_tracking_with_billing' ) ) {
		$t_cost_col = true;
	} else {
		$t_cost_col = false;
	}

?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="hidden" name="id" value="<?php echo isset( $f_bug_id ) ? $f_bug_id : 0 ?>" />
<table border=0 class="width100" cellspacing="0">
<tr>
	<td class="form-title" colspan="4">
<?php
		collapse_icon( 'bugnotestats' );
?>
		<?php echo lang_get( 'time_tracking' ) ?>
	</td>
</tr>
<tr class="row-2">
        <td class="category" width="25%">
                <?php
		$t_filter = array();
		$t_filter['do_filter_by_date'] = 'on';
		$t_filter['start_day'] = $t_bugnote_stats_from_d;
		$t_filter['start_month'] = $t_bugnote_stats_from_m;
		$t_filter['start_year'] = $t_bugnote_stats_from_y;
		$t_filter['end_day'] = $t_bugnote_stats_to_d;
		$t_filter['end_month'] = $t_bugnote_stats_to_m;
		$t_filter['end_year'] = $t_bugnote_stats_to_y;
		print_filter_do_filter_by_date(true);
		?>
        </td>
</tr>
<?php if ( $t_cost_col ) { ?>
<tr class="row-1">
	<td>
		<?php echo lang_get( 'time_tracking_cost' ) ?>:
		<input type="text" name="bugnote_cost" value="<?php echo $f_bugnote_cost ?>" />
	</td>
</tr>
<?php } ?>
<tr>
        <td class="center" colspan="2">
                <input type="submit" class="button" name="get_bugnote_stats_button" value="<?php echo lang_get( 'time_tracking_get_info_button' ) ?>" />
        </td>
</tr>

</table>
</form>
<?php
if ( !is_blank( $f_get_bugnote_stats_button ) ) {
	$t_from = "$t_bugnote_stats_from_y-$t_bugnote_stats_from_m-$t_bugnote_stats_from_d";
	$t_to = "$t_bugnote_stats_to_y-$t_bugnote_stats_to_m-$t_bugnote_stats_to_d";
	$t_bugnote_stats = bugnote_stats_get_project_array( $f_project_id, $t_from, $t_to, $f_bugnote_cost );

	if ( is_blank( $f_bugnote_cost ) || ( (double)$f_bugnote_cost == 0 ) ) {
		$t_cost_col = false;
    }

	$t_prev_id = -1;
?>
<br />
<table class="width100" cellpadding="2">
<tbody><tr>
<?php
  # Excel export
  #$f_bug_array stores the number of the selected rows
  #$t_bug_arr_sort is used for displaying
  #$f_export is a string for the word and excel pages

  $t_icon_path = config_get( 'icon_path' );
  $t_excel_cost = $t_cost_col ? "&amp;bugnote_cost=".$f_bugnote_cost : "";
?>

<tr>
  <td>
    <a href="billing_excel.php?from=<?=$t_from?>&amp;to=<?=$t_to?><?=$t_excel_cost?>" title="Excel 2000"><img src="<?=$t_icon_path?>fileicons/xls.gif" border="0" align="absmiddle" alt="Excel" /></a>
  <td>
</tr>
</tbody></table>
<br />
<table border="0" class="width100" cellspacing="0">
<tr class="row-category-history">
	<td class="small-caption">
		<?php echo lang_get( 'username' ) ?>
	</td>
	<td class="small-caption">
		<?php echo lang_get( 'time_tracking' ) ?>
	</td>
<?php if ( $t_cost_col) { ?>
	<td class="small-caption">
		<?php echo lang_get( 'time_tracking_cost' ) ?>
	</td>
<?php } ?>

</tr>
<?php
	$t_sum_in_minutes = 0;
	$t_sum_cost = 0;

	foreach ( $t_bugnote_stats as $t_item ) {
		$t_sum_in_minutes += $t_item['sum_time_tracking'];
		if ($t_cost_col) {
		  $t_sum_cost += $t_item['cost'];
		}

		$t_item['sum_time_tracking'] = db_minutes_to_hhmm( $t_item['sum_time_tracking'] );
		if ( $t_item['bug_id'] != $t_prev_id) {
			$t_link = string_get_bug_view_link( $t_item['bug_id'] ) . ": " . string_display( $t_item['summary'] );
			echo '<tr class="row-category-history"><td colspan="4">' . $t_link . "</td></tr>";
			$t_prev_id = $t_item['bug_id'];
		}
?>
<tr <?php echo helper_alternate_class() ?>>
	<td class="small-caption">
		<?php echo $t_item['username'] ?>
	</td>
	<td class="small-caption">
		<?php echo $t_item['sum_time_tracking'] ?>
	</td>
<?php if ($t_cost_col) { ?>
	<td>
		<?php echo string_attribute( number_format( $t_item['cost'], 2 ) ); ?>
	</td>
<?php } ?>
</tr>
<?php } # end for loop 
?>
<tr <?php echo helper_alternate_class() ?>>
	<td class="small-caption">
		<?php echo lang_get( 'total_time' ); ?>
	</td>
	<td class="small-caption">
		<?php echo db_minutes_to_hhmm( $t_sum_in_minutes ); ?>
	</td>
<?php if ($t_cost_col) { ?>
  <td>
    <?php echo string_attribute( number_format( $t_sum_cost, 2 ) ); ?>
  </td>
<?php } ?>
</tr>
</table>
<?php } # end if ?>
<?php
	collapse_end( 'bugnotestats' );
?>
billing_inc.php (7,410 bytes)   
billing_excel.php (5,899 bytes)   
<?php
# Mantis - a php based bugtracking system

# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
# Copyright (C) 2002 - 2007  Mantis Team   - mantisbt-dev@lists.sourceforge.net

# Mantis is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# Mantis is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mantis.  If not, see <http://www.gnu.org/licenses/>.

  # --------------------------------------------------------
  # $Id:$
  # --------------------------------------------------------
?>
<?php
  # This include file prints out the bug bugnote_stats
  require_once( 'core.php' );
  
  $t_core_path = config_get( 'core_path' );
  $t_mantis_dir = dirname( __FILE__ ) . DIRECTORY_SEPARATOR;
  
  $t_core_path = config_get( 'core_path' );

  require_once( $t_core_path.'bugnote_api.php' );
  
  if ( ! config_get('time_tracking_enabled') )
    return;

  $f_from = gpc_get_string('from', '');
  $f_to = gpc_get_string('to', '');
  $f_bugnote_cost = gpc_get_int( 'bugnote_cost', '' );
  $f_project_id = helper_get_current_project();

  if ( ON == config_get( 'time_tracking_with_billing' ) ) {
    $t_cost_col = true;
  } else {
    $t_cost_col = false;
  }
    
  if ( !is_blank( $f_from ) && !is_blank( $f_to ) ) {
    
    # get the fields list
    $t_field_name_arr = array( lang_get( 'id' ), lang_get( 'summary' ), lang_get( 'username' ), lang_get( 'time_tracking' ), lang_get( 'time_tracking_cost' ) );
    $field_name_count = count( $t_field_name_arr );
    if ( !$t_cost_col ) {
      $field_name_count--;  // Remove cost
    }
    
    helper_begin_long_process();
  
    # excel or html export
    $t_export_title = helper_get_default_export_filename( '' );
    $t_export_title = ereg_replace( '[\/:*?"<>|]', '', $t_export_title );
  
    # Make sure that IE can download the attachments under https.
    header( 'Pragma: public' );
  
    header( 'Content-Type: application/vnd.ms-excel' );
  
    if ( preg_match( "/MSIE/", $_SERVER["HTTP_USER_AGENT"] ) ) {
      header( 'Content-Disposition: attachment; filename="' . urlencode( $t_export_title ) . '.xls"' ) ;
    } else {
      header( 'Content-Disposition: attachment; filename="' . $t_export_title . '.xls"' );
    }
    $t_bugnote_stats = bugnote_stats_get_project_array( $f_project_id, $f_from, $f_to, $f_bugnote_cost );
  
    if ( is_blank( $f_bugnote_cost ) || ( (double)$f_bugnote_cost == 0 ) ) {
      $t_cost_col = false;
    }
  
    $t_prev_id = -1;
    
    echo( 
"<?xml version=\"1.0\"?>
<?mso-application progid=\"Excel.Sheet\"?>" );
?>
<Workbook
   xmlns="urn:schemas-microsoft-com:office:spreadsheet"
   xmlns:o="urn:schemas-microsoft-com:office:office"
   xmlns:x="urn:schemas-microsoft-com:office:excel"
   xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
   xmlns:html="http://www.w3.org/TR/REC-html40">
  <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
    <Author>Mantis</Author>
    <LastAuthor>Mantis</LastAuthor>
    <Created><? echo( date('c')); ?></Created>
    <Company></Company>
    <Version>11.8036</Version>
  </DocumentProperties>
  <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
    <WindowHeight>6795</WindowHeight>
    <WindowWidth>8460</WindowWidth>
    <WindowTopX>120</WindowTopX>
    <WindowTopY>15</WindowTopY>
    <ProtectStructure>False</ProtectStructure>
    <ProtectWindows>False</ProtectWindows>
  </ExcelWorkbook>
  <Styles>
    <Style ss:ID="Default" ss:Name="Normal">
      <Alignment ss:Vertical="Bottom" />
      <Borders />
      <Font />
      <Interior />
      <NumberFormat />
      <Protection />
    </Style>
    <Style ss:ID="s21">
      <Font x:Family="Swiss" ss:Bold="1" />
    </Style>
  </Styles>
  <Worksheet ss:Name="<? echo( lang_get( 'time_tracking_billing_link' ) ); ?>">
    <Table ss:ExpandedColumnCount="<?php echo $field_name_count; ?>" ss:ExpandedRowCount="<?php echo( count($t_bugnote_stats)+1); ?>"
           x:FullColumns="1" x:FullRows="1">
<Row>
<?php for ( $i=0 ; $i <$field_name_count ; $i++ ) { ?>
  <Cell ss:StyleID="s21"><Data ss:Type="String"><?php echo $t_field_name_arr[$i]; ?></Data></Cell>
<?php } //for ?>
</Row>

<?php
  foreach ( $t_bugnote_stats as $t_item ) {
?>
<Row>
  <Cell><Data ss:Type="Number"><?php echo $t_item['bug_id']; ?></Data></Cell>
  <Cell><Data ss:Type="String"><?php echo $t_item['summary']; ?></Data></Cell>
  <Cell><Data ss:Type="String"><?php echo $t_item['username']; ?></Data></Cell>
  <Cell><Data ss:Type="Number"><?php echo $t_item['sum_time_tracking']; ?></Data></Cell>
<?php if ($t_cost_col) { ?>
  <Cell><Data ss:Type="Number"><?php echo string_attribute( number_format( $t_item['cost'], 2 ) ); ?></Data></Cell>
<?php } ?>
</Row>
<?php } # end for loop ?>  
 
    </Table>
    <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
      <Print>
        <ValidPrinterInfo />
        <HorizontalResolution>600</HorizontalResolution>
        <VerticalResolution>600</VerticalResolution>
      </Print>
      <Selected />
      <Panes>
        <Pane>
          <Number>3</Number>
          <ActiveRow>5</ActiveRow>
          <ActiveCol>1</ActiveCol>
        </Pane>
      </Panes>
      <ProtectObjects>False</ProtectObjects>
      <ProtectScenarios>False</ProtectScenarios>
    </WorksheetOptions>
  </Worksheet>
</Workbook>
<?php } # end if ?>
billing_excel.php (5,899 bytes)   
7932.zip (4,740 bytes)

Relationships

related to 0015301 acknowledged mantisbt CSV / Excel export with customizable fields for the Time Tracking menu 
has duplicate 0013903 closedatrol mantisbt Timetracking to recurse subprojets 
related to 0013706 assignedAbsolutelyFreeWeb Plugin - Time Tracking csv export for time tracking 

Activities

rprouse

rprouse

2007-11-16 13:20

reporter   ~0016242

This would make the billing feature really usable. It would be great if you had the option of exporting the high level report shown on the billing page, or a more detailed one broken down to the notes for each issue. This would really help with invoicing.

rprouse

rprouse

2007-12-21 16:57

reporter   ~0016496

I have uploaded the files for this feature. I implemented it on Mantis 1.1.0.

billing_export.patch is a patch on billing_inc.php to add my changes. Or you could just use billing_inc.php if it has not changed since 1.1.0. My changes to this file add a link to export to Excel and includes the total billing along with the total time at the bottom of the page.

billing_excel.php is the page that is linked to that does the actual export.

I used the code from the original billing export, so permissions should be ok. I also used all of the language strings, so no translations are needed.

Let me know if you want any changes.

vboctor

vboctor

2007-12-29 04:14

manager   ~0016517

Thanks rprouse for your contribution.

I've updated the patch contributed by rprouse and attached it as 7932.zip. Following are my changes:

  1. <?= syntax for PHP is not used in Mantis and was being ignored by my PHP installation. This was causing several bugs.

  2. Used tabs for indentation rather than spaces.

  3. Some fixes in standard compliance.

The problem that occurs now is that Excel complains that the format of the file is not consistent with the extension and asks the users if they trust the file. It would be nice if we can fix that.

With the current layout, I am not sure of the advantage of the xls over a simple csv.

rprouse

rprouse

2008-01-07 21:28

reporter   ~0016580

I will convert to CSV export. I think that you are right and that is better.

siebrand

siebrand

2009-06-13 04:09

developer   ~0022128

Unassigned after having been assigned for well over a year without progress.

johannbell

johannbell

2009-09-18 06:04

reporter   ~0022964

is it possible to add more fields to the export file like start_date, end_date, etc... ?

pierre

pierre

2012-02-21 03:16

reporter   ~0031274

Hi there. Would be VERY interested if this was solved ;-)

yany

yany

2012-12-14 19:02

reporter   ~0034545

Should I submit a new issue if I would be pleased if we could get a CSV export of the simple "Time Tracking" (not the billing) charts with customizable columns?

dregad

dregad

2012-12-16 04:57

developer   ~0034549

@yany - yes, on principle we like to stick with "one bug/feature = one issue in the tracker" so if you can't find an existing issue requesting what you want, you should definitely open another one (and refer to this one as they are anyway related)

yany

yany

2012-12-17 05:43

reporter   ~0034565

Thank you dregad, I have posted it: 0015301

vboctor

vboctor

2015-12-12 21:21

manager   ~0052116

Pull Request: https://github.com/mantisbt/mantisbt/pull/691

Related Changesets

MantisBT: master dba48137

2015-12-12 14:15

vboctor


Details Diff
Support exporting billing report to CSV and Excel

- Added billing_api.php
- Implemented 'Export to Excel' using billing api
- Implemented 'Export to CSV' using billing api

Will open a code cleanup bug to move more code to use billing_api.

Fixes 0007932
Affected Issues
0007932
add - billing_export_to_csv.php Diff File
add - billing_export_to_excel.php Diff File
mod - billing_inc.php Diff File
add - core/billing_api.php Diff File