[ Index ]

PHP Cross Reference of Eventum

title

Body

[close]

/include/ -> class.customer_stats_report.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 encoding=utf-8: */
   3  // +----------------------------------------------------------------------+
   4  // | Eventum - Issue Tracking System                                      |
   5  // +----------------------------------------------------------------------+
   6  // | Copyright (c) 2003, 2004, 2005, 2006, 2007 MySQL AB                  |
   7  // |                                                                      |
   8  // | This program is free software; you can redistribute it and/or modify |
   9  // | it under the terms of the GNU General Public License as published by |
  10  // | the Free Software Foundation; either version 2 of the License, or    |
  11  // | (at your option) any later version.                                  |
  12  // |                                                                      |
  13  // | This program is distributed in the hope that it will be useful,      |
  14  // | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
  15  // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
  16  // | GNU General Public License for more details.                         |
  17  // |                                                                      |
  18  // | You should have received a copy of the GNU General Public License    |
  19  // | along with this program; if not, write to:                           |
  20  // |                                                                      |
  21  // | Free Software Foundation, Inc.                                       |
  22  // | 59 Temple Place - Suite 330                                          |
  23  // | Boston, MA 02111-1307, USA.                                          |
  24  // +----------------------------------------------------------------------+
  25  // | Authors: Bryan Alsdorf <bryan@mysql.com>                             |
  26  // +----------------------------------------------------------------------+
  27  //
  28  // @(#) $Id: class.customer_stats_report.php 3246 2007-02-09 09:10:12Z glen $
  29  //
  30  
  31  require_once (APP_INC_PATH . "class.error_handler.php");
  32  require_once (APP_INC_PATH . "class.time_tracking.php");
  33  require_once(APP_PEAR_PATH . "Math/Stats.php");
  34  
  35  /**
  36   * The Customer Stats report will be too complex to group with the rest of
  37   * the reports so I am seperating it into a seperate class.
  38   *
  39   * @version 1.0
  40   * @author Bryan Alsdorf <bryan@mysql.com>
  41   */
  42  
  43  class Customer_Stats_Report
  44  {
  45      /**
  46       * The ID of the project this report is for.
  47       * @var integer
  48       */
  49      var $prj_id;
  50  
  51      /**
  52       * Support Levels to show
  53       * @var array
  54       */
  55      var $levels;
  56  
  57      /**
  58       * Customers to display stats for
  59       * @var array
  60       */
  61      var $customers;
  62  
  63      /**
  64       * Start date of the report
  65       * @var string
  66       */
  67      var $start_date;
  68  
  69      /**
  70       * End date of the report
  71       * @var string
  72       */
  73      var $end_date;
  74  
  75      /**
  76       * The current customer restriction
  77       * @var array
  78       */
  79      var $current_customers;
  80  
  81      /**
  82       * If expired contracts should be excluded.
  83       * @var boolean
  84       */
  85      var $exclude_expired_contracts;
  86  
  87      /**
  88       * An array listing the union of time tracking categories that have data.
  89       * @var array
  90       */
  91      var $time_tracking_categories = array();
  92  
  93      /**
  94       * Class Constructor. Accepts the support level, customer,
  95       * start date and end date to be used in this report. If a customer is
  96       * specified the support level is ignored. If the date is left off or invalid all dates are included.
  97       *
  98       * @access  public
  99       * @param   integer $prj_id The id of the project this report is for.
 100       * @param   array $levels The support levels that should be shown in this report.
 101       * @param   array $customers The customers this report should be for.
 102       * @param   string $start_date The start date of this report.
 103       * @param   string $end_date The end date of this report.
 104       */
 105      function Customer_Stats_Report($prj_id, $levels, $customers, $start_date, $end_date)
 106      {
 107          $this->prj_id = $prj_id;
 108          $this->levels = $levels;
 109          $this->customers = $customers;
 110          $this->start_date = $start_date;
 111          $this->end_date = $end_date;
 112      }
 113  
 114  
 115      /**
 116       * Returns all data for this report.
 117       *
 118       * @access  public
 119       * @return  array
 120       */
 121      function getData()
 122      {
 123          $data = array();
 124  
 125          // determine if this should be customer based or support level based.
 126          if ($this->isCustomerBased()) {
 127              // customer based
 128  
 129              // get "all" row of data
 130              $data[] = $this->getAllRow();
 131  
 132              foreach ($this->customers as $customer_id) {
 133                  $details = Customer::getDetails($this->prj_id, $customer_id);
 134                  $data[] = $this->getDataRow($details["customer_name"], array($customer_id));
 135              }
 136          } else {
 137              // support level based
 138              if (count($this->levels) > 0) {
 139                  $grouped_levels = Customer::getGroupedSupportLevels($this->prj_id);
 140                  foreach ($this->levels as $level_name) {
 141                      if ($level_name == "Aggregate") {
 142                          // get "all" row of data
 143                          $data[] = $this->getAllRow();
 144                          continue;
 145                      }
 146  
 147                      $support_options = array();
 148                      if ($this->exclude_expired_contracts) {
 149                          $support_options[] = CUSTOMER_EXCLUDE_EXPIRED;
 150                      }
 151                      $customers = Customer::getListBySupportLevel($this->prj_id, $grouped_levels[$level_name], $support_options);
 152                      $data[] = $this->getDataRow($level_name, $customers);
 153                  }
 154              }
 155          }
 156  
 157          return $data;
 158      }
 159  
 160  
 161      /**
 162       * Returns data row for specified name and customers.
 163       *
 164       * @param   string  $name Name of data row.
 165       * @param   string  $customers  Customers to include in this row.
 166       * @return  array   An array of data.
 167       */
 168      function getDataRow($name, $customers)
 169      {
 170          $this->current_customers = $customers;
 171          return array(
 172              "title" =>  $name,
 173              "customer_counts"   =>  $this->getCustomerCounts($name),
 174              "issue_counts"  =>  $this->getIssueCounts($name),
 175              "email_counts"  =>  $this->getEmailCounts(),
 176              "time_tracking" =>  $this->getTimeTracking(),
 177              "time_stats"    =>  $this->getTimeStats()
 178          );
 179      }
 180  
 181  
 182      /**
 183       * Returns the "all" row, that is the row that always appears at the top of the report
 184       * and covers all support levels and customers regardless of what is selected.
 185       *
 186       * @access  private
 187       * @return  array The array of data for this row.
 188       */
 189      function getAllRow()
 190      {
 191          $row = array(
 192              "title" =>  ev_gettext("Aggregate")
 193          );
 194  
 195          // get complete list of customers.
 196          $all_levels = array();
 197          $levels = Customer::getSupportLevelAssocList($this->prj_id);
 198          foreach ($levels as $level_id => $level_name) {
 199              $all_levels[] = $level_id;
 200          }
 201          if ($this->exclude_expired_contracts) {
 202              $support_option = CUSTOMER_EXCLUDE_EXPIRED;
 203          } else {
 204              $support_option = array();
 205          }
 206          $this->current_customers = Customer::getListBySupportLevel($this->prj_id, $all_levels, $support_option);
 207  
 208          // get customers
 209          $row["customer_counts"] = $this->getCustomerCounts("All");
 210  
 211          // get total # of issues, avg issues per customer, median issues per customer
 212          $row['issue_counts'] = $this->getIssueCounts("All");
 213  
 214          // get actions counts such as # of customer actions per issue, avg customer actions per issue,
 215          // median customer actions per issue.
 216          $row['email_counts'] = $this->getEmailCounts();
 217  
 218          // get time tracking information
 219          $row['time_tracking'] = $this->getTimeTracking();
 220  
 221          // get other time related stats such as avg and median time between issues and avg and median time to close.
 222          $row['time_stats'] = $this->getTimeStats();
 223  
 224          return $row;
 225      }
 226  
 227  
 228      /**
 229       * Returns various customer statistics.
 230       *
 231       * @access  private
 232       * @param   string $name The name of this data row.
 233       * @return  array Array of statistics
 234       */
 235      function getCustomerCounts($name)
 236      {
 237          $customer_count = count($this->current_customers);
 238  
 239          // split by low/medium/high
 240          $issue_counts = $this->getIssueCountsByCustomer($name);
 241          $activity = array(
 242              'low' => 0,
 243              'medium' => 0,
 244              'high' => 0
 245          );
 246          if ((is_array($issue_counts)) && (count($issue_counts) > 0)) {
 247              foreach ($issue_counts as $count) {
 248                  if ($count <= 2) {
 249                      $activity['low']++;
 250                  } elseif ($count > 2 && $count <= 8) {
 251                      $activity['medium']++;
 252                  } elseif ($count > 8) {
 253                      $activity['high']++;
 254                  }
 255              }
 256          }
 257          if ($customer_count > 0) {
 258              foreach ($activity as $key => $value) {
 259                  $activity[$key] = ($value * 100) / $customer_count;
 260              }
 261              $inactive_count = ((($customer_count - count($issue_counts)) * 100) / $customer_count);
 262          } else {
 263              $inactive_count = 0;
 264          }
 265  
 266          return array(
 267                  "customer_count"    =>  $customer_count,
 268                  "activity"  =>  $activity,
 269                  "active"    =>  count($issue_counts),
 270                  "inactive"  =>  $inactive_count
 271          );
 272      }
 273  
 274  
 275      /**
 276       * Returns the counts relating to number of issues.
 277       *  - total: total number of issues for the support level.
 278       *  - avg: Average number of issues opened by customers for support level.
 279       *  - median: Median number of issues opened by customers for support level.
 280       *
 281       * @access  private
 282       * @param   string $name The name of this data row.
 283       * @return  array Array of counts.
 284       */
 285      function getIssueCounts($name)
 286      {
 287          $issue_counts = $this->getIssueCountsByCustomer($name);
 288          if ((is_array($issue_counts)) && (count($issue_counts) > 0)) {
 289              $stats = new Math_Stats();
 290              $stats->setData($issue_counts);
 291  
 292              return array(
 293                  "total" =>  $stats->sum(),
 294                  "avg"   =>  $stats->mean(),
 295                  "median"    =>  $stats->median(),
 296                  "max"   =>  $stats->max()
 297              );
 298          } else {
 299              return array(
 300                  "total" =>  0,
 301                  "avg"   =>  0,
 302                  "median"    =>  0,
 303                  "max"   =>  0
 304              );
 305          }
 306      }
 307  
 308      /**
 309       * Returns an array of issue counts for customers.
 310       *
 311       * @access  private
 312       * @param   string $name The name of this data row.
 313       */
 314      function getIssueCountsByCustomer($name)
 315      {
 316          static $issue_counts;
 317  
 318          // poor man's caching system...
 319          if (!empty($issue_counts[$name])) {
 320              return $issue_counts[$name];
 321          }
 322  
 323          $stmt = "SELECT
 324                      count(*)
 325                   FROM
 326                      " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue
 327                   WHERE
 328                      " . $this->getWhereClause("iss_customer_id", "iss_created_date") . "
 329                   GROUP BY
 330                      iss_customer_id";
 331          $res = $GLOBALS["db_api"]->dbh->getCol($stmt);
 332          if (PEAR::isError($res)) {
 333              Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
 334              return "";
 335          }
 336          $issue_counts[$name] = $res;
 337          return $res;
 338      }
 339  
 340  
 341      /**
 342       * Returns the counts relating to # of customer and developer emails.
 343       *
 344       * @access  public
 345       * @return  array Array of counts.
 346       */
 347      function getEmailCounts()
 348      {
 349          $counts = array(
 350              "customer"  =>  array(),
 351              "developer" =>  array()
 352          );
 353          $stmt = "SELECT
 354                      count(*)
 355                   FROM
 356                      " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "support_email,
 357                      " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "email_account,
 358                      " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue,
 359                      " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "project_user
 360                   WHERE
 361                      sup_ema_id = ema_id AND
 362                      sup_iss_id = iss_id AND
 363                      sup_usr_id = pru_usr_id AND
 364                      ema_prj_id = pru_prj_id AND
 365                      pru_role = " . User::getRoleID('Customer') . " AND
 366                      " . $this->getWhereClause("iss_customer_id", "sup_date") . "
 367                   GROUP BY
 368                      sup_iss_id";
 369          $res = $GLOBALS["db_api"]->dbh->getCol($stmt);
 370          if (PEAR::isError($res)) {
 371              Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
 372              return array();
 373          }
 374  
 375          if (count($res) > 0) {
 376              $stats = new Math_Stats();
 377              $stats->setData($res);
 378  
 379              $counts["customer"]["total"] = $stats->sum();
 380              $counts["customer"]["avg"] = $stats->mean();
 381              $counts["customer"]["median"] = $stats->median();
 382          } else {
 383              $counts["customer"]["total"] = 0;
 384              $counts["customer"]["avg"] = 0;
 385              $counts["customer"]["median"] = 0;
 386          }
 387  
 388          $stmt = "SELECT
 389                      count(*)
 390                   FROM
 391                      " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "support_email,
 392                      " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "email_account,
 393                      " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue,
 394                      " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "project_user
 395                   WHERE
 396                      sup_ema_id = ema_id AND
 397                      sup_iss_id = iss_id AND
 398                      sup_usr_id = pru_usr_id AND
 399                      ema_prj_id = pru_prj_id AND
 400                      pru_role != " . User::getRoleID('Customer') . " AND
 401                      " . $this->getWhereClause("iss_customer_id", "sup_date") . "
 402                   GROUP BY
 403                      sup_iss_id";
 404          $res = $GLOBALS["db_api"]->dbh->getCol($stmt);
 405          if (PEAR::isError($res)) {
 406              Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
 407              return array();
 408          }
 409          if (count($res) > 0) {
 410              $stats = new Math_Stats();
 411              $stats->setData($res);
 412  
 413              $counts["developer"]["total"] = $stats->sum();
 414              $counts["developer"]["avg"] = $stats->mean();
 415              $counts["developer"]["median"] = $stats->median();
 416          } else {
 417              $counts["developer"]["total"] = 0;
 418              $counts["developer"]["avg"] = 0;
 419              $counts["developer"]["median"] = 0;
 420          }
 421  
 422          return $counts;
 423      }
 424  
 425  
 426      /**
 427       * Returns information from time tracking module, split by category
 428       *
 429       * @access  private
 430       * @return  array Array of counts.
 431       */
 432      function getTimeTracking()
 433      {
 434          $time = array();
 435  
 436          // get total stats
 437          $time[0] = $this->getIndividualTimeTracking();
 438          $time[0]["name"] = "Total";
 439          $this->time_tracking_categories[0] = "Total";
 440  
 441          // get categories
 442          $categories = Time_Tracking::getAssocCategories();
 443          foreach ($categories as $ttc_id => $category) {
 444              $individual = $this->getIndividualTimeTracking($ttc_id);
 445              if (count($individual) > 0) {
 446                  $time[$ttc_id] = $individual;
 447                  $time[$ttc_id]["name"] = $category;
 448  
 449                  $this->time_tracking_categories[$ttc_id] = $category;
 450              }
 451          }
 452  
 453          return $time;
 454      }
 455  
 456  
 457      /**
 458       * Returns time tracking information for a certain category, or all categories if no category is passed.
 459       *
 460       * @access  public
 461       * @param   $ttc_id The id of the time tracking category. Default false
 462       * @return  array Array of time tracking information
 463       */
 464      function getIndividualTimeTracking($ttc_id = false)
 465      {
 466          $stmt = "SELECT
 467                      ttr_time_spent
 468                   FROM
 469                      " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "time_tracking,
 470                      " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue
 471                   WHERE
 472                      ttr_iss_id = iss_id";
 473          if ($ttc_id != false) {
 474              $stmt .= "\n AND ttr_ttc_id = $ttc_id";
 475          }
 476          $stmt .= "\nAND " . $this->getWhereClause("iss_customer_id", "ttr_created_date");
 477          $res = $GLOBALS["db_api"]->dbh->getCol($stmt);
 478          if (PEAR::isError($res)) {
 479              Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
 480              return array();
 481          }
 482          if (count($res) > 0) {
 483              $stats = new Math_Stats();
 484              $stats->setData($res);
 485              $total = $stats->sum();
 486              $avg = $stats->mean();
 487              $median = $stats->median();
 488              return array(
 489                  "total" =>  $total,
 490                  "total_formatted"   =>  Misc::getFormattedTime($total, true),
 491                  "avg"   =>  $avg,
 492                  "avg_formatted" =>  Misc::getFormattedTime($avg),
 493                  "median"=>  $median,
 494                  "median_formatted"  =>  Misc::getFormattedTime($median),
 495              );
 496          } else {
 497              return array();
 498          }
 499      }
 500  
 501  
 502      /**
 503       * Returns information about time to close and time to first response.
 504       *
 505       * @access  private
 506       * @return  array Array of counts.
 507       */
 508      function getTimeStats()
 509      {
 510          // time to close
 511          $stmt = "SELECT
 512                      round(((unix_timestamp(iss_closed_date) - unix_timestamp(iss_created_date)) / 60))
 513                   FROM
 514                      " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue
 515                   WHERE
 516                      iss_closed_date IS NOT NULL AND
 517                      " . $this->getWhereClause("iss_customer_id", array("iss_created_date", "iss_closed_date"));
 518          $res = $GLOBALS["db_api"]->dbh->getCol($stmt);
 519          if (PEAR::isError($res)) {
 520              Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
 521              return array();
 522          }
 523          if (count($res) > 0) {
 524              $stats = new Math_Stats();
 525              $stats->setData($res);
 526  
 527              $time_to_close = array(
 528                  "avg"   =>  $stats->mean(),
 529                  "avg_formatted" =>  Misc::getFormattedTime($stats->mean()),
 530                  "median"=>  $stats->median(),
 531                  "median_formatted"  =>  Misc::getFormattedTime($stats->median()),
 532                  "max"   =>  $stats->max(),
 533                  "max_formatted" =>  Misc::getFormattedTime($stats->max()),
 534                  "min"   =>  $stats->min(),
 535                  "min_formatted" =>  Misc::getFormattedTime($stats->min())
 536              );
 537          } else {
 538              $time_to_close = array(
 539                  "avg"   =>  0,
 540                  "avg_formatted" =>  Misc::getFormattedTime(0),
 541                  "median"=>  0,
 542                  "median_formatted"  =>  Misc::getFormattedTime(0),
 543                  "max"   =>  0,
 544                  "max_formatted" =>  Misc::getFormattedTime(0),
 545                  "min"   =>  0,
 546                  "min_formatted" =>  Misc::getFormattedTime(0)
 547              );
 548          }
 549  
 550          // time to first response
 551          $stmt = "SELECT
 552                      round(((unix_timestamp(iss_first_response_date) - unix_timestamp(iss_created_date)) / 60))
 553                   FROM
 554                      " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "issue
 555                   WHERE
 556                      iss_first_response_date IS NOT NULL AND
 557                      " . $this->getWhereClause("iss_customer_id", array("iss_created_date", "iss_closed_date"));
 558          $res = $GLOBALS["db_api"]->dbh->getCol($stmt);
 559          if (PEAR::isError($res)) {
 560              Error_Handler::logError(array($res->getMessage(), $res->getDebugInfo()), __FILE__, __LINE__);
 561              return array();
 562          }
 563          if (count($res) > 0) {
 564              $stats = new Math_Stats();
 565              $stats->setData($res);
 566  
 567              $time_to_first_response = array(
 568                  "avg"   =>  $stats->mean(),
 569                  "avg_formatted" =>  Misc::getFormattedTime($stats->mean()),
 570                  "median"=>  $stats->median(),
 571                  "median_formatted"  =>  Misc::getFormattedTime($stats->median()),
 572                  "max"   =>  $stats->max(),
 573                  "max_formatted" =>  Misc::getFormattedTime($stats->max()),
 574                  "min"   =>  $stats->min(),
 575                  "min_formatted" =>  Misc::getFormattedTime($stats->min())
 576              );
 577          } else {
 578              $time_to_first_response = array(
 579                  "avg"   =>  0,
 580                  "avg_formatted" =>  Misc::getFormattedTime(0),
 581                  "median"=>  0,
 582                  "median_formatted"  =>  Misc::getFormattedTime(0),
 583                  "max"   =>  0,
 584                  "max_formatted" =>  Misc::getFormattedTime(0),
 585                  "min"   =>  0,
 586                  "min_formatted" =>  Misc::getFormattedTime(0)
 587              );
 588          }
 589  
 590          return array(
 591              "time_to_close" => $time_to_close,
 592              "time_to_first_response"    =>  $time_to_first_response
 593          );
 594      }
 595  
 596  
 597      /**
 598       * Returns if this report is customer based
 599       *
 600       * @return  boolean
 601       */
 602      function isCustomerBased()
 603      {
 604          return ((is_array($this->customers)) && (count($this->customers) > 0) && (!in_array("", $this->customers)));
 605      }
 606  
 607  
 608      /**
 609       * Sets if expired contracts should be exclude
 610       *
 611       * @access  public
 612       * @param   boolean $split If expired contracts should be excluded
 613       */
 614      function excludeExpired($exclude)
 615      {
 616          $this->exclude_expired_contracts = $exclude;
 617      }
 618  
 619  
 620      /**
 621       * Returns where clause based on what the current support level/customer is set to, and date range currently set.
 622       * If $date_field is an array, the fields will be ORed together.
 623       *
 624       * @param   string $customer_field The name of customer_id field
 625       * @param   mixed $date_field The name of the date field
 626       * @return  string A string with the SQL limiting the resultset
 627       */
 628      function getWhereClause($customer_field, $date_field)
 629      {
 630          $where = '';
 631          if (!empty($customer_field)) {
 632              if (count($this->current_customers) > 0) {
 633                  $where .= $customer_field . " IN(" . join(",",$this->current_customers) . ")";
 634              } else {
 635                  // XXX: this is a dirty hack to handle support levels that don't have customers, but I can't think of anything better right now.
 636                  $where .= "1 = 2";
 637              }
 638          }
 639  
 640  
 641          if ((!empty($this->start_date)) && (!empty($this->end_date))) {
 642              if (!empty($customer_field)) {
 643                  $where .= " AND\n";
 644              }
 645              if (is_array($date_field)) {
 646                  $date_conditions = array();
 647                  foreach ($date_field as $field) {
 648                      $date_conditions[] = "($field BETWEEN '" . $this->start_date . "' AND '" . $this->end_date . "')";
 649                  }
 650                  $where .= "(" . join(" OR ", $date_conditions) . ")";
 651              } else {
 652                  $where .= "($date_field BETWEEN '" . $this->start_date . "' AND '" . $this->end_date . "')";
 653              }
 654          }
 655          return $where;
 656      }
 657  
 658  
 659      /**
 660       * Returns the text for the row label. Will be "Support Level" if viewing support levels and "Customer" if viewing a specific customer.
 661       *
 662       * @access  public
 663       * @return  string The text for the row label.
 664       */
 665      function getRowLabel()
 666      {
 667          if ($this->isCustomerBased()) {
 668              return ev_gettext("Customer");
 669          } else {
 670              return ev_gettext("Support Level");
 671          }
 672      }
 673  
 674  
 675      /**
 676       * Returns an array of graph types
 677       *
 678       * @access  public
 679       * @return  array An array of graph types
 680       */
 681      function getGraphTypes()
 682      {
 683          return array(
 684              1   =>  array(
 685                          "title" =>  ev_gettext("Total Workload by Support Level"),
 686                          "desc"  =>  ev_gettext("Includes issue count, Developer email Count, Customer Email Count, Customers count by Support Level"),
 687                          "size"  => array(
 688                                          "x" =>  800,
 689                                          "y" =>  350
 690                          )
 691              ),
 692              2   =>  array(
 693                          "title" =>  ev_gettext("Avg Workload per Customer by Support Level"),
 694                          "desc"  =>  ev_gettext("Displays average number of issues, developer emails and customer emails per issue by support level"),
 695                          "size"  =>  array(
 696                                          "x" =>  800,
 697                                          "y" =>  350
 698                          ),
 699                          "value_format"  =>  "%.1f"
 700              ),
 701              3   =>  array(
 702                          "title" =>  ev_gettext("Avg and Median Time to Close by Support Level"),
 703                          "desc"  =>  ev_gettext("Displays time stats"),
 704                          "size"  =>  array(
 705                                          "x" =>  600,
 706                                          "y" =>  350
 707                          ),
 708                          "y_label"   =>  ev_gettext("Days")
 709              ),
 710              4   =>  array(
 711                          "title" =>  ev_gettext("Avg and Median Time to First Response by Support Level"),
 712                          "desc"  =>  ev_gettext("Displays time stats"),
 713                          "size"  =>  array(
 714                                          "x" =>  600,
 715                                          "y" =>  350
 716                          ),
 717                          "y_label"   =>  ev_gettext("Hours")
 718              )
 719          );
 720      }
 721  
 722  
 723      /**
 724       * Returns the list of sections that can be displayed.
 725       *
 726       * @access  public
 727       * @return  array An array of sections.
 728       */
 729      function getDisplaySections()
 730      {
 731          return array(
 732              "customer_counts"   =>  ev_gettext("Customer Counts"),
 733              "issue_counts"  =>  ev_gettext("Issue Counts"),
 734              "email_counts"  =>  ev_gettext("Email Counts"),
 735              "time_stats"    =>  ev_gettext("Time Statistics"),
 736              "time_tracking" =>  ev_gettext("Time Tracking")
 737          );
 738      }
 739  
 740      /**
 741       * Returns the list of time tracking categories that have data.
 742       *
 743       * @access  public
 744       * @return  array An array of time tracking categories
 745       */
 746      function getTimeTrackingCategories()
 747      {
 748          return $this->time_tracking_categories;
 749      }
 750  }
 751  
 752  // benchmarking the included file (aka setup time)
 753  if (APP_BENCHMARK) {
 754      $GLOBALS['bench']->setMarker('Included Customer_Stats_Report Class');
 755  }


Generated: Wed Dec 19 21:21:33 2007 Cross-referenced by PHPXref 0.7