Thursday, February 20, 2014

Creating your own project and time tracking reports

Introduction

With the new projects version 2 module we have created a very powerful and flexible reporting system. We supply open source reports written in PHP so anybody with PHP knowledge can create their own reports.

The reports that come with Group-Office are located in “modules/projects2/report”. There are already reports about time tracking of employees, project information and a general overview of all projects.

All these reports extend a simple abstract class that holds some basic functionality.



Creating the PHP code

It's best to keep your own reports in your data folder (defined in $config['file_storage_path']='/home/groupoffice'). The projects module automatically detects reports in “/home/groupoffice/php/projects2/report”.

So if you would create a report called “MyReport” then you must create the file “MyReport.php” there. Remember that everything is case sensitive!

In MyReport.php define the class name like this:



The start “GOFS” in the class name will instruct the Group-Office class loader to look in the home folder for this report.

In the abstract class there are 3 methods that will control when this report template will be available:

  1. supportsSelectedProject
  2. supportsBatchReport
  3. supportedProjectTypes

It can show up when you run a batch report from the main toolbar in the module or when a project container or project was selected through the “New” → “Report” menu option.

In the following example we create an Excel report using the PHPExcel library.



<?php
/**
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Intermesh BV 
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

/**
 * Simple XLSX report for project information
 *
 */
class GO_Projects2_Report_MyReport extends GO_Projects2_Report_Abstract {

 /**
  * Return filename extension.
  * @return string
  */
 public function fileExtension() {
  return 'xlsx';
 }

 /**
  * Return the name of the report used in the drop down
  * 
  * @return string
  */
 public function name() {
  return 'My Excel report';
 }

 /**
  * With this enabled it will only show up if this report is created from the
  * "New" menu in a project.
  * 
  * @return boolean defaults to false
  */
 public function supportsSelectedProject() {
  return true;
 }

 /**
  * With this enables it shows up when you create a report from the main toolbar
  * in the projects module.
  * 
  * @return boolean
  */
 public function supportsBatchReport() {
  return false;
 }

 /**
  * Indicates which project types are accepted for this report.
  * @return boolean Array containing for example: GO_Projects2_Model_Template::PROJECT_TYPE_PROJECT or GO_Projects2_Model_Template::PROJECT_TYPE_CONTAINER
  */
 public function supportedProjectTypes() {
  return array(GO_Projects2_Model_Template::PROJECT_TYPE_PROJECT);
 }

 /**
  * Indicate whether this report supports a start and end date
  * 
  * @return boolean defaults to false
  */
 public function supportsDateRange() {
  return false;
 }

 /**
  * Indicate whether this report supports a start and end date
  * 
  * @return boolean defaults to false
  */
 public function supportsStatusFilter() {
  return false;
 }

 /**
  *
  * @var GO_Base_Util_Excel 
  */
 private $_xls;

 /**
  * Start rendering the report.
  * 
  * @param boolean $return to return the file data as string.
  */
 public function render($return = false) {


  $this->project->id;

  //Create an Excel object. See http://www.codeplex.com/PHPExcel) for more 
  //information
  $this->_xls = new GO_Base_Util_Excel();

  $this->_xls->getProperties()->setCreator(GO::user()->name);
  $this->_xls->getProperties()->setLastModifiedBy(GO::user()->name);

  $this->_xls->getProperties()->setTitle($this->name());
  $this->_xls->getProperties()->setSubject($this->project->path);

  $this->_xls->setActiveSheetIndex(0);
  $this->_xls->getActiveSheet()->setTitle("Project information");


  $this->_xls->setDefaultStyle('Arial', 12);
  $this->_xls->setDefaultWidth(15);

  $this->_xls->setCellValue('A1', GO::t('strName'));
  $this->_xls->setCellValue('B1', $this->project->path);


  $this->_xls->setCellValue('A2', GO::t('status', 'projects2'));
  $this->_xls->setCellValue('B2', $this->project->status->name);

  $this->_xls->setCellValue('A3', GO::t('startTime', 'projects2'));
  $this->_xls->setCellValue('B3', $this->project->getAttribute('start_time', 'formatted'));


  $this->_xls->setCellValue('A4', GO::t('projectDue_time', 'projects2'));
  $this->_xls->setCellValue('B4', $this->project->getAttribute('due_time', 'formatted'));

  $this->_xls->setCellValue('A5', GO::t('lag', 'projects2'));
  $this->_xls->setCellValue('B5', GO_Base_Util_Date::minutesToTimeString($this->project->getLag()));

  $this->_xls->setCellValue('A6', GO::t('strDescription'));
  $this->_xls->setCellValue('B6', $this->project->description);
  $this->_xls->getActiveSheet()->getStyle("B6:B6")->getAlignment()->setWrapText(true);


  $file = GO_Base_Fs_File::tempFile($this->filename, $this->fileExtension());


  $this->_xls->save($file->path());


  if ($return) {
   //we must return it as string   
   $content = $file->getContents();
   $file->delete();
   return $content;
  } else {

   //we output it to the browser
   GO_Base_Util_Http::outputDownloadHeaders($file);
   $file->output();
  }
 }

}


Ending

I hope this simple example gets you started with project reports. The existing PDF reports are also a great resource to help you get going.

3 comments: