Preparation for report destination PDF/Printer and Excel (and Open Office Calc)
authorJoe Hunt <joe.hunt.consulting@gmail.com>
Mon, 2 Mar 2009 10:32:42 +0000 (10:32 +0000)
committerJoe Hunt <joe.hunt.consulting@gmail.com>
Mon, 2 Mar 2009 10:32:42 +0000 (10:32 +0000)
12 files changed:
CHANGELOG.txt
reporting/includes/ExcelWriterXML.php [new file with mode: 0644]
reporting/includes/ExcelWriterXML_Sheet.php [new file with mode: 0644]
reporting/includes/ExcelWriterXML_Style.php [new file with mode: 0644]
reporting/includes/excel_report.inc [new file with mode: 0644]
reporting/includes/pdf_report.inc
reporting/includes/reports_classes.inc
reporting/rep701.php
reporting/rep705.php
reporting/rep706.php
reporting/rep707.php
reporting/reports_main.php

index e6d19612538c6cdec14d6642e4f61899f161c880..a9d8f67495b45b786d9a0df81603dab0be464496 100644 (file)
@@ -19,6 +19,20 @@ Legend:
 ! -> Note
 $ -> Affected files
 
+02-Mar-2009 Joe Hunt
++ Preparation for report destination PDF/Printer and Excel (and Open Office Calc)
+$ /reporting/includes/reports_classes.inc
+  /reporting/includes/pdf_report.inc
+  /reporting/includes/ExcelWriterXML.php (new file)
+  /reporting/includes/ExcelWriterXML_Sheet.php (new file)
+  /reporting/includes/ExcelWriterXM__Style (new file)
+  /reporting/includes/excel_report.inc (new file)
+  /reporting/reports_main.php
+  /reporting/rep701.php
+  /reporting/rep705.php
+  /reporting/rep706.php
+  /reporting/rep707.php
+  
 01-Mar-2009 Janusz Dobrowolski
 # Setting magic_quotes_gpc and register_globals to off in htaccess file
 $ /.htaccess (new)
diff --git a/reporting/includes/ExcelWriterXML.php b/reporting/includes/ExcelWriterXML.php
new file mode 100644 (file)
index 0000000..0f617d5
--- /dev/null
@@ -0,0 +1,483 @@
+<?php
+/**
+ * ExcelWriterXML Package
+ * Used the schema documentation from Microsoft
+ * @link http://msdn.microsoft.com/en-us/library/aa140066(office.10).aspx
+ * @package ExcelWriterXML
+ */
+
+/**
+ * Includes the other class file to create Sheets
+ */
+include('ExcelWriterXML_Sheet.php');
+/**
+ * Includes the other class file to create Styles
+ */
+include('ExcelWriterXML_Style.php');
+
+/**
+ * Class for generating the initial Excel XML document
+ * <code>
+ * <?php
+ * $xml = new ExcelWriterXML;
+ * $format = $xml->addStyle('StyleHeader');
+ * $format->fontBold();
+ * $sheet = $xml->addSheet('Test Sheet');
+ * $sheet->writeString (1,1,'Header1','StyleHeader');
+ * $sheet->writeString(2,1,'My String');
+ * $xml->sendHeaders();
+ * $xml->writeData();
+ * ?>
+ * </code>
+ * @link http://msdn.microsoft.com/en-us/library/aa140066(office.10).aspx
+ * @author Robert F Greer
+ * @version 1.0
+ * @package ExcelWriterXML
+ */
+class ExcelWriterXML
+{
+       // Private Variables //
+       var $styles = array();
+       var $formatErrors = array();
+       var $sheets = array();
+       var $showErrorSheet = false;
+       var $overwriteFile = false;
+       var $docFileName;
+       var $docTitle;
+       var $docSubject;
+       var $docAuthor;
+       var $docCreated;
+       var $docManager;
+       var $docCompany;
+       var $docVersion = 11.9999;
+       var $charSet = "utf-8"; // 2009-02-28 Added by Joe Hunt, FA
+       ///////////////////////
+
+       /**
+     * Constructor for the ExcelWriterXML class.
+     * A default style is created, a filename is generated (if not supplied) and
+     * the create time of the document is stored.
+     * @param string $fileName This is the filename that will be passed to the
+     * browser.  If not present it will default to "file.xml"
+     * @return ExcelWriterXML Instance of the class
+     */
+       function ExcelWriterXML($fileName = 'file.xml')
+       {
+               // Add default style
+               $style = $this->addStyle('Default');
+               $style->name('Normal');
+               $style->alignVertical('Bottom');
+               
+               if ($fileName == '')
+               {
+                       $fileName = 'file.xml';
+                       $this->_addError(__FUNCTION__,'File name was blank, default to "file.xml"');
+               }
+               
+               $this->docFileName = $fileName;
+               $this->docCreated = date('Y-m-d').'T'.date('H:i:s').'Z';
+       }
+
+       /**
+        * Whether or not to overwrite a file (when writing to disk)
+        * @param boolean $overwrite True or False
+        */
+       function overwriteFile($overwrite = true)
+       {
+               if (!is_bool($overwrite))
+               {
+                       $this->overwriteFile = false;
+                       return;
+               }
+               else
+               {
+                       $this->overwriteFile = $overwrite;
+               }
+       }
+
+       /**
+        * Whether or not to show the sheet containing the Formatting Errors
+        * @param boolean $show
+        */
+       function showErrorSheet($show = true)
+       {
+               if (!is_bool($show))
+               {
+                       $this->showErrorSheet = true;
+                       return;
+               }
+               else{
+                       $this->showErrorSheet = $show;
+               }
+       }
+
+       /**
+        * Adds a format error.  When the document is generated if there are any
+        * errors they will be listed on a seperate sheet.
+        * @param string $function The name of the function that was called
+        * @param string $message Details of the error
+        */
+       function _addError($function, $message)
+       {
+               $tmp = array(
+                       'function'      => $function,
+                       'message'       => $message,
+               );
+               $this->formatErrors[] = $tmp;
+       }
+       
+       /**
+     * Sends the HTML headers to the client.
+     * This is only necessary if the XML doc is to be delivered from the server
+     * to the browser.
+     */
+       function sendHeaders()
+       {
+               header('content-type: text/xml');
+               header('Content-Disposition: attachment; filename="'.$this->docFileName.'"');
+               header('Expires: 0');
+               header('Cache-Control: must-revalidate, post-check=0,pre-check=0');
+               header('Pragma: public');
+       }
+
+       /**
+     * Gets the default style that was created by the contructor.
+     * This is used when modifications to the default style are required.
+     * @return ExcelWriterXML_Style Reference to a style class
+     */
+       function getDefaultStyle()
+       {
+               return($this->styles[0]);
+       }
+
+       /**
+     * Creates a new style for the spreadsheet
+     * @param string $id The name of the style to be referenced within the
+     * spreadsheet
+     * @return ExcelWriterXML_Style Reference to a new style class
+     * @todo Parameter validation for styles, can't have duplicates
+     */
+       /*
+       function addStyle($id)
+       {
+               $style =& new ExcelWriterXML_Style($id);
+               $this->styles[] = $style;
+               return ($style);
+       }
+       */
+       /**
+     * Creates a new style within the spreadsheet.
+     * Styles cannot have the same name as any other style. If a style has the
+     * same name as another style then it will follow the default naming
+     * convention as if $id was null
+     * @param string $id The name of the style.  If left blank then the style
+     * will default to "CustomStyle" + n (e.g. "CustomStyle1")
+     * @return ExcelWriterXML_Style Reference to a new style class
+     */
+       function addStyle($id = null)
+       {
+               static $styleNum = 1;
+               if (trim($id) == '') 
+                       $id = null;
+
+               if ($id == null)
+               {
+                       $id = 'CustomStyle'.$styleNum;
+                       $styleNum++;
+                       //$this->_addError(__FUNCTION__,'Style name was blank, renamed to "'.$id.'"');
+               }
+
+               while (!$this->_checkStyleID($id))
+               {
+                       $old_id = $id;
+                       $id = 'CustomStyle'.$styleNum;
+                       $this->_addError(__FUNCTION__,'Style name was duplicate ("'.$old_id.'"), renamed to "'.$id.'"');
+                       $styleNum++;
+               }
+               
+               $style =& new ExcelWriterXML_Style($id);
+               $this->styles[] = $style;
+               return ($style);
+       }
+       
+       /**
+     * Creates a new sheet within the spreadsheet
+     * At least one sheet is required.
+     * Additional sheets cannot have the same name as any other sheet.
+     * If a sheet has the same name as another sheet then it will follow the
+     * default naming convention as if $id was null
+     * @param string $id The name of the sheet.  If left blank then the sheet
+     * will default to "Sheet" + n (e.g. "Sheet1")
+     * @return ExcelWriterXML_Sheet Reference to a new sheet class
+     */
+       function addSheet($id = null)
+       {
+               static $sheetNum = 1;
+               if (trim($id) == '') 
+                       $id = null;
+
+               if ($id == null)
+               {
+                       $id = 'Sheet'.$sheetNum;
+                       $sheetNum++;
+                       $this->_addError(__FUNCTION__,'Sheet name was blank, renamed to "'.$id.'"');
+               }
+
+               while (!$this->_checkSheetID($id))
+               {
+                       $old_id = $id;
+                       $id = 'Sheet'.$sheetNum;
+                       $this->_addError(__FUNCTION__,'Sheet name was duplicate ("'.$old_id.'"), renamed to "'.$id.'"');
+                       $sheetNum++;
+               }
+               
+               $sheet =& new ExcelWriterXML_Sheet($id);
+               $this->sheets[] = $sheet;
+               return ($sheet);
+       }
+       
+       /**
+        * Checks whether a proposed Sheet ID has already been used
+        * @param string $id The sheet id to be checked
+        * @return boolean True if the id is unique, false otherwise
+        */
+       function _checkSheetID($id){
+               foreach($this->sheets as $sheet)
+               {
+                       $sheetID = $sheet->getID();
+                       if ($id == $sheetID)
+                       {
+                               return false;
+                       }
+               }
+               return true;
+       }
+
+       /**
+        * Checks whether a proposed Style ID has already been used
+        * @param string $id The style id to be checked
+        * @return boolean True if the id is unique, false otherwise
+        */
+       function _checkStyleID($id)
+       {
+               foreach($this->styles as $style)
+               {
+                       $styleID = $style->getID();
+                       if ($id == $styleID)
+                       {
+                               return false;
+                       }
+               }
+               return true;
+       }
+
+       // 2009-02-28 Added by Joe Hunt, FA
+    function setCharSet($charset)
+    {
+               $this->charSet = $charset;
+       }       
+       /**
+     * Writes the XML data
+     * @param string $target If left null the function will output to STD OUT
+     * (e. g. browser or console)
+     */
+       function writeData($target = null)
+       {
+               $docTitle = '';
+               $docSubject = '';
+               $docAuthor = '';
+               $docCreated = '';
+               $docManager = '';
+               $docCompany = '';
+               $docVersion = 12;
+               
+               $errors = false;
+               
+               if ($this->showErrorSheet == true)
+               {
+                       $format = $this->addStyle('formatErrorsHeader');
+                       $format->fontBold();
+                       $format->bgColor('red');
+               }
+               
+               if (!empty($this->docTitle)) 
+                       $docTitle = '<Title>'.htmlspecialchars($this->docTitle).'</Title>'."\r";
+               if (!empty($this->docSubject)) 
+                       $docSubject = '<Subject>'.htmlspecialchars($this->docSubject).'</Subject>'."\r";
+               if (!empty($this->docAuthor)) 
+                       $docAuthor = '<Author>'.htmlspecialchars($this->docAuthor).'</Author>'."\r";
+               if (!empty($this->docCreated)) 
+                       $docCreated = '<Created>'.htmlspecialchars($this->docCreated).'</Created>'."\r";
+               if (!empty($this->docManager)) 
+                       $docManager = '<Manager>'.htmlspecialchars($this->docManager).'</Manager>'."\r";
+               if (!empty($this->docCompany)) 
+                       $docCompany = '<Company>'.htmlspecialchars($this->docCompany).'</Company>'."\r";
+                       //$docCompany = '<Company>'.$this->docCompany.'</Company>'."\r";
+               
+               $xml = '<?xml version="1.0" encoding="'.$this->charSet.'"?>'."\r";  // 2009-02-28 Added by Joe Hunt, FA
+               $xml .= '<?mso-application progid="Excel.Sheet"?>'."\r";
+               $xml .= '<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">'."\r";
+               $xml .= '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">'."\r";
+               if (!empty($this->docTitle))    
+                       $xml .= '       '.$docTitle;
+               if (!empty($this->docSubject))  
+                       $xml .= '       '.$docSubject;
+               if (!empty($this->docAuthor))   
+                       $xml .= '       '.$docAuthor;
+               if (!empty($this->docCreated))  
+                       $xml .= '       '.$docCreated;
+               if (!empty($this->docManager))  
+                       $xml .= '       '.$docManager;
+               if (!empty($this->docCompany))  
+                       $xml .= '       '.$docCompany;
+               $xml .= '       <Version>'.$this->docVersion.'</Version>'."\r";
+               $xml .= '</DocumentProperties>'."\r";
+               $xml .= '<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel" />'."\r";
+               $xml .= '<Styles>'."\r";
+               foreach($this->styles as $style)
+               {
+                       $xml .= $style->getStyleXML();
+                       if (count($style->getErrors()) > 0)
+                       {
+                               $errors = true;
+                       }
+               }
+               $xml .= '</Styles>'."\r";
+               if (count($this->sheets) == 0)
+               {
+                       $this->addSheet();
+               }
+               foreach($this->sheets as $sheet)
+               {
+                       $xml .= $sheet->getSheetXML();
+                       if (count($sheet->getErrors()) > 0)
+                       {
+                               $errors = true;
+                       }
+               }
+               if (count($this->formatErrors) > 0)
+               {
+                       $errors = true;
+               }
+               
+               if ($errors == true && $this->showErrorSheet == true)
+               {
+                       $sheet = $this->addSheet('formatErrors');
+                       $sheet->cellMerge(1,1,3,0);     // Merge the first three cells across in row 1
+                       $sheet->writeString(1,1,'Formatting Errors');
+                       $sheet->writeString(2,1,'Type','formatErrorsHeader');
+                       $sheet->writeString(2,2,'Function','formatErrorsHeader');
+                       $sheet->cellWidth(2,1,200);
+                       $sheet->cellWidth(2,2,200);
+                       $sheet->cellWidth(2,3,400);
+                       $sheet->writeString(2,3,'Error Message','formatErrorsHeader');
+                       $row = 3;
+                       foreach($this->formatErrors as $error)
+                       {
+                               $function = $error['function'];
+                               $message = $error['message'];
+                               $sheet->writeString($row,1,'Document');
+                               $sheet->writeString($row,2,$function);
+                               $sheet->writeString($row,3,$message);
+                               $row++;
+                       }
+                       foreach($this->styles as $styleObject)
+                       {
+                               $formatErrors = $styleObject->getErrors();
+                               $styleID = 'Style='.$styleObject->getID();
+                               foreach($formatErrors as $error)
+                               {
+                                       $function = $error['function'];
+                                       $message = $error['message'];
+                                       $sheet->writeString($row,1,$styleID);
+                                       $sheet->writeString($row,2,$function);
+                                       $sheet->writeString($row,3,$message);
+                                       $row++;
+                               }
+                       }               
+                       foreach($this->sheets as $sheetObject)
+                       {
+                               $formatErrors = $sheetObject->getErrors();
+                               $sheetID = 'Sheet='.$sheetObject->getID();
+                               foreach($formatErrors as $error)
+                               {
+                                       $function = $error['function'];
+                                       $message = $error['message'];
+                                       $sheet->writeString($row,1,$sheetID);
+                                       $sheet->writeString($row,2,$function);
+                                       $sheet->writeString($row,3,$message);
+                                       $row++;
+                               }
+                       }
+                       $xml .= $sheet->getSheetXML();
+               }
+               
+               
+               $xml .= '</Workbook>';
+               
+               if ($target == null)
+               {
+                       // We aren't writing this file to disk, so echo back to the client.
+                       echo $xml;
+                       return true;
+               }
+               else
+               {
+                       $fileExists = file_exists($target);
+                       if ($fileExists == true && $this->overwriteFile == false)
+                       {
+                               die('"'.$target.'" exists and "overwriteFile" is set to "false"');
+                       }
+                       $handle = fopen($target, 'w');
+                       if ($handle)
+                       {
+                               fwrite($handle,$xml);
+                               fclose($handle);
+                               return true;
+                       }
+                       else
+                       {
+                               echo('<br/>Not able to open "'.$target.'" for writing');
+                               return false;
+                       }
+               }
+       }
+       
+       /**
+     * Sets the Title of the document
+     * @param string $title Part of the properties of the document.
+     */
+       function docTitle($title = '') { $this->docTitle = $title; }
+
+       /**
+     * Sets the Subject of the document
+     * @param string $subject Part of the properties of the document.
+     */
+       function docSubject($subject = '') { $this->docSubject = $subject; }
+
+       /**
+     * Sets the Author of the document
+     * @param string $author Part of the properties of the document.
+     */
+       function docAuthor($author = '') { $this->docAuthor = $author; }
+
+       /**
+     * Sets the Manager of the document
+     * @param string $manager Part of the properties of the document.
+     */
+       function docManager($manager = '') { $this->docManager = $manager; }
+
+       /**
+     * Sets the Company of the document
+     * @param string $company Part of the properties of the document.
+     */
+       function docCompany($company = '') { $this->docCompany = $company; }
+}
+
+
+?>
\ No newline at end of file
diff --git a/reporting/includes/ExcelWriterXML_Sheet.php b/reporting/includes/ExcelWriterXML_Sheet.php
new file mode 100644 (file)
index 0000000..18588f1
--- /dev/null
@@ -0,0 +1,481 @@
+<?php
+/**
+ * File contains the class files for ExcelWriterXML_Sheet
+ * @package ExcelWriterXML
+ */
+
+/**
+ * Class for generating sheets within the Excel document
+ * @link http://msdn.microsoft.com/en-us/library/aa140066(office.10).aspx
+ * @author Robert F Greer
+ * @version 1.0
+ * @package ExcelWriterXML
+ * @uses ExcelWriterXML_Style::alignHorizontal()
+ * @uses ExcelWriterXML_Style::alignRotate()
+ * @uses ExcelWriterXML_Style::alignShrinktofit()
+ * @uses ExcelWriterXML_Style::alignVertical()
+ * @uses ExcelWriterXML_Style::alignVerticaltext()
+ * @uses ExcelWriterXML_Style::alignWraptext()
+ * @uses ExcelWriterXML_Style::bgColor()
+ * @uses ExcelWriterXML_Style::bgPattern()
+ * @uses ExcelWriterXML_Style::bgPatternColor()
+ * @uses ExcelWriterXML_Style::border()
+ * @uses ExcelWriterXML_Style::checkColor()
+ * @uses ExcelWriterXML_Style::fontBold()
+ * @uses ExcelWriterXML_Style::fontColor()
+ * @uses ExcelWriterXML_Style::fontFamily()
+ * @uses ExcelWriterXML_Style::fontItalic()
+ * @uses ExcelWriterXML_Style::fontName()
+ * @uses ExcelWriterXML_Style::fontOutline()
+ * @uses ExcelWriterXML_Style::fontShadow()
+ * @uses ExcelWriterXML_Style::fontStrikethrough()
+ * @uses ExcelWriterXML_Style::fontUnderline()
+ * @uses ExcelWriterXML_Style::getErrors()
+ * @uses ExcelWriterXML_Style::getID()
+ * @uses ExcelWriterXML_Style::getStyleXML()
+ * @uses ExcelWriterXML_Style::name()
+ * @uses ExcelWriterXML_Style::numberFormat()
+ * @uses ExcelWriterXML_Style::numberFormatDate()
+ * @uses ExcelWriterXML_Style::numberFormatDatetime()
+ * @uses ExcelWriterXML_Style::numberFormatTime()
+ */
+class ExcelWriterXML_Sheet 
+{
+       // Private Variables
+       var $id;
+       var $cells = array();
+       var $colWidth = array();
+       var $rowHeight = array();
+       var $URLs = array();
+       var $mergeCells = array();
+       var $comments = array();
+       var $formatErrors = array();
+       var $displayRightToLeft = false;
+       /////////////////////
+       
+       // Public Variables
+       /////////////////////
+       
+       // Constructor
+       /**
+     * Constructor for a new Sheet
+     * @param string $id The name of the sheet to be referenced within the
+     * spreadsheet
+     */
+       function ExcelWriterXML_Sheet($id)
+       {
+               $this->id = $id;
+       }
+       
+       /**
+        * Function to get the named value of the Sheet
+        * @return string Name of the Sheet
+        */
+       function getID()
+       {
+               return $this->id;
+       }
+       
+       /**
+        * Adds a format error.  When the document is generated if there are any
+        * errors they will be listed on a seperate sheet.
+        * @param string $function The name of the function that was called
+        * @param string $message Details of the error
+        */
+       function _addError($function, $message)
+       {
+               $tmp = array(
+                       'sheet'         => $this->id,
+                       'function'      => $function,
+                       'message'       => $message,
+               );
+               $this->formatErrors[] = $tmp;
+       }
+       
+       /**
+        * Returns any errors found in the sheet
+        * @return mixed Array of errors if they exist, otherwise false
+        */
+       function getErrors()
+       {
+               return($this->formatErrors);
+       }
+
+       /**
+     * Converts a MySQL type datetime field to a value that can be used within
+     * Excel.
+     * If the passed value is not valid then the passed string is sent back.
+     * @param string $datetime Value must in in the format "yyyy-mm-dd hh:ii:ss"
+     * @return string Value in the Excel format "yyyy-mm-ddThh:ii:ss.000"
+     */
+       function convertMysqlDatetime($datetime)
+       {
+               $datetime = trim($datetime);
+               $pattern = "/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/";
+               if (preg_match($pattern, $datetime, $matches)) 
+               {
+                       $datetime = $matches[0];
+                       list($date,$time) = explode(' ',$datetime);
+                       return($date.'T'.$time.'.000');
+               }
+               else
+               {
+                       return($datetime);
+               }
+       }
+       
+       /**
+     * Converts a MySQL type date field to a value that can be used within Excel
+     * If the passed value is not valid then the passed string is sent back.
+     * @param string $datetime Value must in in the format "yyyy-mm-dd hh:ii:ss"
+     * or "yyyy-mm-dd"
+     * @return string Value in the Excel format "yyyy-mm-ddT00:00:00.000"
+     */
+       function convertMysqlDate($datetime)
+       {
+               $datetime = trim($datetime);
+               $pattern1 = "/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/";
+               $pattern2 = "/[0-9]{4}-[0-9]{2}-[0-9]{2}/";
+               if (preg_match($pattern1, $datetime, $matches)) 
+               {
+                       $datetime = $matches[0];
+                       list($date,$time) = explode(' ',$datetime);
+                       return($date.'T'.$time.'.000');
+               }
+               elseif (preg_match($pattern2, $datetime, $matches)) 
+               {
+                       $date = $matches[0];
+                       return($date.'T00:00:00.000');
+               }
+               else
+               {
+                       return($datetime);
+               }
+       }
+       
+       /**
+     * Converts a MySQL type time field to a value that can be used within Excel
+     * If the passed value is not valid then the passed string is sent back.
+     * @param string $datetime Value must in in the format "yyyy-mm-dd hh:ii:ss"
+     * or "hh:ii:ss"
+     * @return string Value in the Excel format "1899-12-31Thh:ii:ss.000"
+     */
+       function convertMysqlTime($datetime)
+       {
+               $datetime = trim($datetime);
+               $pattern1 = "/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/";
+               $pattern2 = "/[0-9]{2}:[0-9]{2}:[0-9]{2}/";
+               if (preg_match($pattern1, $datetime, $matches)) 
+               {
+                       $datetime = $matches[0];
+                       list($date,$time) = explode(' ',$datetime);
+                       return($date.'T'.$time.'.000');
+               }
+               elseif (preg_match($pattern2, $datetime, $matches)) 
+               {
+                       $time = $matches[0];
+                       return('1899-12-31T'.$time.'.000');
+               }
+               else
+               {
+                       return($datetime);
+               }
+       }
+       
+
+       /**
+     * Writes a formula to a cell
+     * From MS
+     * Specifies the formula stored in this cell. All formulas are persisted in
+     * R1C1 notation because they are significantly easier to parse and generate
+     * than A1-style formulas. The formula is calculated upon reload unless
+     * calculation is set to manual. Recalculation of the formula overrides the
+     * value in this cell's Value attribute.
+     * @see writeFormula()
+     * @param string $dataType Type of data that the formula should generate,
+     * "String" "Number" "DateTime"
+     * @param integer $row Row, based upon a "1" based array
+     * @param integer $column Column, based upon a "1" based array
+     * @param string $data Formula data to be written to a cell
+     * @param mixed $style Named style, or style reference to be applied to the
+     * cell
+     */
+       function writeFormula($dataType,$row,$column,$data,$style = null)
+       {
+               if ($dataType != 'String'
+                       && $dataType != 'Number'
+                       && $dataType != 'DateTime')
+               {
+                       $this->_addError(__FUNCTION__,'('.$row.','.$column.') DataType for formula was not valid "'.$dataType.'"');
+                       $halign = 'Automatic';
+               }
+
+               $this->_writeData('String',$row,$column,'',$style,$data);
+       }
+
+       /**
+     * Writes a string to a cell
+     * @see writeData()
+     * @param integer $row Row, based upon a "1" based array
+     * @param integer $column Column, based upon a "1" based array
+     * @param string $data String data to be written to a cell
+     * @param mixed $style Named style, or style reference to be applied to the
+     * cell
+     */
+       function writeString($row,$column,$data,$style = null)
+       {
+               $this->_writeData('String',$row,$column,$data,$style);
+       }
+       
+       /**
+     * Writes a number to a cell.
+     * If the data is not numeric then the function will write the data as a
+     * string.
+     * @see writeData()
+     * @param integer $row Row, based upon a "1" based array
+     * @param integer $column Column, based upon a "1" based array
+     * @param mixed $data Number data to be written to a cell
+     * @param mixed $style Named style, or style reference to be applied to the
+     * cell
+     */
+       function writeNumber($row,$column,$data,$style = null)
+       {
+               if (!is_numeric($data))
+               {
+                       $this->_writeData('String',$row,$column,$data,$style);
+                       $this->_addError(__FUNCTION__,'('.$row.','.$column.') Tried to write non-numeric data to type Number "'.$data.'"');
+               }
+               else
+               {               
+                       $this->_writeData('Number',$row,$column,$data,$style);
+               }
+       }
+       
+       /**
+     * Writes a Date/Time to a cell.
+     * If data is not valid the function will write the passed value as a
+     * string.
+     * @see writeData()
+     * @param integer $row Row, based upon a "1" based array
+     * @param integer $column Column, based upon a "1" based array
+     * @param string $data Date or Time data to be written to a cell.  This must
+     * be in the format "yyyy-mm-ddThh:ii:ss.000" for Excel to recognize it.
+     * @param mixed $style Named style, or style reference to be applied to the
+     * cell
+     */
+       function writeDateTime($row,$column,$data,$style = null)
+       {
+               $pattern = "/[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.000/";
+               if (preg_match($pattern, $data, $matches)) 
+               {
+                       $data = $matches[0];
+                       $this->_writeData('DateTime',$row,$column,$data,$style);
+               }
+               else
+               {
+                       $this->_writeData('String',$row,$column,$data,$style);
+                       $this->_addError(__FUNCTION__,'('.$row.','.$column.') Tried to write invalid datetime data to type DateTime "'.$data.'"');
+               }
+       }
+       function _writeData($type,$row,$column,$data,$style = null,$formula = null)
+       {
+               if ($style != null)
+               {
+                       if (gettype($style) == 'object')
+                       {
+                               if (get_class($style) == 'ExcelWriterXML_Style')
+                               {
+                                       $styleID = $style->getID();
+                               }
+                               else
+                               {
+                                       $this->_addError(__FUNCTION__,'('.$row.','.$column.') StyleID supplied was an object, but not a style object "'.get_class($style).'"');
+                                       $styleID = null;
+                               }
+                       }
+                       else
+                       {
+                               $styleID = $style;
+                       }
+               }
+               else
+               {
+                       $styleID = null;
+               }
+               
+               $cell = array(
+                       'type'          => $type,
+                       'style'         => $styleID,
+                       'data'          => $data,
+                       'formula'       => $formula,
+               );
+               $this->cells[$row][$column] = $cell;
+       }
+       
+       /**
+        * Displays the sheet in Right to Left format
+        */
+       function displayRightToLeft()
+       {
+               $this->displayRightToLeft = true;
+       }
+
+       /**
+     * Called by the ExcelWriterXML class to get the XML data for this object
+     * @return string Contains only the XML data for the sheet
+     */
+       function getSheetXML()
+       {
+               ksort($this->cells);
+               
+               $displayRightToLeft = ($this->displayRightToLeft) ? 'ss:RightToLeft="1"' : '';
+               
+               $xml = '<Worksheet ss:Name="'.$this->id.'" '.$displayRightToLeft.'>'."\r";
+               $xml .= '       <Table>'."\r";
+               foreach($this->colWidth as $colIndex => $colWidth)
+               {
+                         $xml .= '             <Column ss:Index="'.$colIndex.'" ss:AutoFitWidth="0" ss:Width="'.$colWidth.'"/>'."\r";
+               }
+               foreach($this->cells as $row => $rowData)
+               {
+                       ksort($rowData);
+                       if (isset($this->rowHeight[$row]))
+                       {
+                               $rowHeight = 'ss:AutoFitHeight="0" ss:Height="'.$this->rowHeight[$row].'"';
+                       }
+                       else
+                       {
+                               $rowHeight = '';
+                       }
+                       $xml .= '               <Row ss:Index="'.$row.'" '.$rowHeight.' >'."\r";
+                       foreach($rowData as $column => $cell)
+                       {
+                               if (!empty($cell['formula'])) 
+                                       $formula = 'ss:Formula="'.$cell['formula'].'"';
+                               else 
+                                       $formula = '';
+                               if (!empty($cell['style'])) 
+                                       $style = 'ss:StyleID="'.$cell['style'].'"';
+                               else 
+                                       $style = '';
+                               if (empty($this->URLs[$row][$column])) 
+                                       $URL = '';
+                               else 
+                                       $URL = 'ss:HRef="'.htmlspecialchars($this->URLs[$row][$column]).'"';
+                               if (empty($this->mergeCells[$row][$column])) 
+                                       $mergeCell = '';
+                               else 
+                                       $mergeCell = 'ss:MergeAcross="'.$this->mergeCells[$row][$column]['width'].'" ss:MergeDown="'.$this->mergeCells[$row][$column]['height'].'"';
+                               if (empty($this->comments[$row][$column])) 
+                                       $comment = '';
+                               else
+                               {
+                                       $comment = '                                    <Comment ss:Author="'.$this->comments[$row][$column]['author'].'">'."\r";
+                                       $comment .= '                                   <ss:Data xmlns="http://www.w3.org/TR/REC-html40">'."\r";
+                                       $comment .= '                                   <B><Font html:Face="Tahoma" x:CharSet="1" html:Size="8" html:Color="#000000">'.htmlspecialchars($this->comments[$row][$column]['author']).':</Font></B>'."\r";
+                                       $comment .= '                                   <Font html:Face="Tahoma" x:CharSet="1" html:Size="8" html:Color="#000000">'.htmlspecialchars($this->comments[$row][$column]['comment']).'</Font>'."\r";
+                                       $comment .= '                                   </ss:Data>'."\r";
+                                       $comment .= '                                   </Comment>'."\r";
+                               }
+                               $type = $cell['type'];
+                               $data = $cell['data'];
+                               
+                               $xml .= '                       <Cell '.$style.' ss:Index="'.$column.'" '.$URL.' '.$mergeCell.' '.$formula.'>'."\r";
+                               $xml .= '                               <Data ss:Type="'.$type.'">';
+                               $xml .= htmlspecialchars($data);
+                               $xml .= '</Data>'."\r";
+                               $xml .= $comment;
+                               $xml .= '                       </Cell>'."\r";
+                       }
+                       $xml .= '               </Row>'."\r";
+               }
+               $xml .= '       </Table>'."\r";
+               $xml .= '</Worksheet>'."\r";
+               return($xml);
+       }
+
+       /**
+     * Alias for function columnWidth()
+     */
+       function cellWidth( $row, $col,$width = 48) { $this->columnWidth($col,$width); }
+
+       /**
+     * Sets the width of a cell.
+     * Sets  the width of the column that the cell resides in.
+     * Cell width of zero effectively hides the column
+     * @param integer $row Row, based upon a "1" based array
+     * @param integer $col Column, based upon a "1" based array
+     * @param mixed $width Width of the cell/column, default is 48
+     */
+       function columnWidth( $col,$width = 48) { $this->colWidth[$col] = $width; }
+
+       /**
+     * Alias for function rowHeight()
+     */
+       function cellHeight( $row, $col,$height = 12.5) { $this->rowHeight($row,$height); }
+
+       /**
+     * Sets the height of a cell.
+     * Sets  the height of the column that the cell resides in.
+     * Cell height of zero effectively hides the row
+     * @param integer $row Row, based upon a "1" based array
+     * @param integer $col Column, based upon a "1" based array
+     * @param mixed $height Height of the cell/column, default is 12.5
+     */
+       function rowHeight( $row,$height = 12.5) { $this->rowHeight[$row] = $height; }
+
+       /**
+     * Makes the target cell a link to a URL
+     * @param integer $row Row, based upon a "1" based array
+     * @param integer $col Column, based upon a "1" based array
+     * @param string $URL The URL that the link should point to
+     */
+       function addURL( $row, $col,$URL) { $this->URLs[$row][$col] = $URL; }
+       
+       /**
+     * Merges 2 or more cells.
+     * The function acts like a bounding box, with the row and column defining
+     * the upper left corner, and the width and height extending the box.
+     * If width or height are zero (or ommitted) then the function does nothing.
+     * @param integer $row Row, based upon a "1" based array
+     * @param integer $col Column, based upon a "1" based array
+     * @param integer $width Number of cells to the right to merge with
+     * @param integer $height Number of cells down to merge with
+     */
+       function cellMerge($row,$col, $width = 0, $height = 0)
+       {
+               if ($width < 0 || $height < 0)
+               {
+                       $this->_addError(__FUNCTION__,'('.$row.','.$col.') Tried to merge cells with width/height < 0 "(w='.$width.',h='.$height.')"');
+                       return;
+               }
+               
+               $this->mergeCells[$row][$col] = array(
+                       'width'         => $width,
+                       'height'        => $height,
+               );
+               /* I don't think this code is necessary
+               if (!isset($cells[$row][$col]))
+               {
+                       $this->writeString($row,$col,'');
+               }
+               */
+       }
+       
+       /**
+     * Adds a comment to a cell
+     * @param integer $row Row, based upon a "1" based array
+     * @param integer $col Column, based upon a "1" based array
+     * @param string $comment The comment to be displayed on the cell
+     * @param string $author The comment will show a bold header displaying the
+     * author
+     */
+       function addComment( $row, $col,$comment,$author = 'SYSTEM')
+       {
+               $this->comments[$row][$col] = array(
+                       'comment'       => $comment,
+                       'author'        => $author,
+               );
+       }
+}
+?>
\ No newline at end of file
diff --git a/reporting/includes/ExcelWriterXML_Style.php b/reporting/includes/ExcelWriterXML_Style.php
new file mode 100644 (file)
index 0000000..15d231f
--- /dev/null
@@ -0,0 +1,870 @@
+<?php
+/**
+ * File contains the class files for ExcelWriterXML_Style
+ * @package ExcelWriterXML
+ */
+
+/**
+ * Style class for generating Excel styles
+ * @link http://msdn.microsoft.com/en-us/library/aa140066(office.10).aspx
+ * @author Robert F Greer
+ * @version 1.0
+ * @package ExcelWriterXML
+ */
+class ExcelWriterXML_Style 
+{
+       // Private Variables
+       /////////////////////
+       // Options
+       var $id;
+       var $name;
+       var $useAlignment = false;
+       var $useFont = false;
+       var $useBorder = false;
+       var $useInterior = false;
+       
+       // Alignment
+       var $valign;
+       var $halign;
+       var $rotate;
+       var $shrinktofit = 0;
+       var $verticaltext = 0;
+       var $wraptext = 0;
+
+       // Font
+       var $fontColor = 'Automatic';
+       var $fontName;
+       var $fontFamily;
+       var $fontSize;
+       var $bold;
+       var $italic;
+       var $underline;
+       var $strikethrough;
+       var $shadow;
+       var $outline;
+       /////////////////////
+       
+       // Borders
+       var $borderTop = array();
+       var $borderBottom = array();
+       var $borderLeft = array();
+       var $borderRight = array();
+       var $borderDL = array();
+       var $borderDR = array();
+       /////////////////////
+       
+       // Interior
+       var $interiorColor;
+       var $interiorPattern;
+       var $interiorPatternColor;
+       ////////////////////
+       
+       // NumberFormat
+       var $numberFormat;
+       /////////////////////
+       
+       // Other Vars
+       var $formatErrors = array();
+       var $namedColorsIE = array (
+               'aliceblue' => '#F0F8FF',
+               'antiquewhite' => '#FAEBD7',
+               'aqua' => '#00FFFF',
+               'aquamarine' => '#7FFFD4',
+               'azure' => '#F0FFFF',
+               'beige' => '#F5F5DC',
+               'bisque' => '#FFE4C4',
+               'black' => '#000000',
+               'blanchedalmond' => '#FFEBCD',
+               'blue' => '#0000FF',
+               'blueviolet' => '#8A2BE2',
+               'brown' => '#A52A2A',
+               'burlywood' => '#DEB887',
+               'cadetblue' => '#5F9EA0',
+               'chartreuse' => '#7FFF00',
+               'chocolate' => '#D2691E',
+               'coral' => '#FF7F50',
+               'cornflowerblue' => '#6495ED',
+               'cornsilk' => '#FFF8DC',
+               'crimson' => '#DC143C',
+               'cyan' => '#00FFFF',
+               'darkblue' => '#00008B',
+               'darkcyan' => '#008B8B',
+               'darkgoldenrod' => '#B8860B',
+               'darkgray' => '#A9A9A9',
+               'darkgreen' => '#006400',
+               'darkkhaki' => '#BDB76B',
+               'darkmagenta' => '#8B008B',
+               'darkolivegreen' => '#556B2F',
+               'darkorange' => '#FF8C00',
+               'darkorchid' => '#9932CC',
+               'darkred' => '#8B0000',
+               'darksalmon' => '#E9967A',
+               'darkseagreen' => '#8FBC8F',
+               'darkslateblue' => '#483D8B',
+               'darkslategray' => '#2F4F4F',
+               'darkturquoise' => '#00CED1',
+               'darkviolet' => '#9400D3',
+               'deeppink' => '#FF1493',
+               'deepskyblue' => '#00BFFF',
+               'dimgray' => '#696969',
+               'dodgerblue' => '#1E90FF',
+               'firebrick' => '#B22222',
+               'floralwhite' => '#FFFAF0',
+               'forestgreen' => '#228B22',
+               'fuchsia' => '#FF00FF',
+               'gainsboro' => '#DCDCDC',
+               'ghostwhite' => '#F8F8FF',
+               'gold' => '#FFD700',
+               'goldenrod' => '#DAA520',
+               'gray' => '#808080',
+               'green' => '#008000',
+               'greenyellow' => '#ADFF2F',
+               'honeydew' => '#F0FFF0',
+               'hotpink' => '#FF69B4',
+               'indianred' => '#CD5C5C',
+               'indigo' => '#4B0082',
+               'ivory' => '#FFFFF0',
+               'khaki' => '#F0E68C',
+               'lavender' => '#E6E6FA',
+               'lavenderblush' => '#FFF0F5',
+               'lawngreen' => '#7CFC00',
+               'lemonchiffon' => '#FFFACD',
+               'lightblue' => '#ADD8E6',
+               'lightcoral' => '#F08080',
+               'lightcyan' => '#E0FFFF',
+               'lightgoldenrodyellow' => '#FAFAD2',
+               'lightgreen' => '#90EE90',
+               'lightgrey' => '#D3D3D3',
+               'lightpink' => '#FFB6C1',
+               'lightsalmon' => '#FFA07A',
+               'lightseagreen' => '#20B2AA',
+               'lightskyblue' => '#87CEFA',
+               'lightslategray' => '#778899',
+               'lightsteelblue' => '#B0C4DE',
+               'lightyellow' => '#FFFFE0',
+               'lime' => '#00FF00',
+               'limegreen' => '#32CD32',
+               'linen' => '#FAF0E6',
+               'magenta' => '#FF00FF',
+               'maroon' => '#800000',
+               'mediumaquamarine' => '#66CDAA',
+               'mediumblue' => '#0000CD',
+               'mediumorchid' => '#BA55D3',
+               'mediumpurple' => '#9370DB',
+               'mediumseagreen' => '#3CB371',
+               'mediumslateblue' => '#7B68EE',
+               'mediumspringgreen' => '#00FA9A',
+               'mediumturquoise' => '#48D1CC',
+               'mediumvioletred' => '#C71585',
+               'midnightblue' => '#191970',
+               'mintcream' => '#F5FFFA',
+               'mistyrose' => '#FFE4E1',
+               'moccasin' => '#FFE4B5',
+               'navajowhite' => '#FFDEAD',
+               'navy' => '#000080',
+               'oldlace' => '#FDF5E6',
+               'olive' => '#808000',
+               'olivedrab' => '#6B8E23',
+               'orange' => '#FFA500',
+               'orangered' => '#FF4500',
+               'orchid' => '#DA70D6',
+               'palegoldenrod' => '#EEE8AA',
+               'palegreen' => '#98FB98',
+               'paleturquoise' => '#AFEEEE',
+               'palevioletred' => '#DB7093',
+               'papayawhip' => '#FFEFD5',
+               'peachpuff' => '#FFDAB9',
+               'peru' => '#CD853F',
+               'pink' => '#FFC0CB',
+               'plum' => '#DDA0DD',
+               'powderblue' => '#B0E0E6',
+               'purple' => '#800080',
+               'red' => '#FF0000',
+               'rosybrown' => '#BC8F8F',
+               'royalblue' => '#4169E1',
+               'saddlebrown' => '#8B4513',
+               'salmon' => '#FA8072',
+               'sandybrown' => '#F4A460',
+               'seagreen' => '#2E8B57',
+               'seashell' => '#FFF5EE',
+               'sienna' => '#A0522D',
+               'silver' => '#C0C0C0',
+               'skyblue' => '#87CEEB',
+               'slateblue' => '#6A5ACD',
+               'slategray' => '#708090',
+               'snow' => '#FFFAFA',
+               'springgreen' => '#00FF7F',
+               'steelblue' => '#4682B4',
+               'tan' => '#D2B48C',
+               'teal' => '#008080',
+               'thistle' => '#D8BFD8',
+               'tomato' => '#FF6347',
+               'turquoise' => '#40E0D0',
+               'violet' => '#EE82EE',
+               'wheat' => '#F5DEB3',
+               'white' => '#FFFFFF',
+               'whitesmoke' => '#F5F5F5',
+               'yellow' => '#FFFF00',
+               'yellowgreen' => '#9ACD32',
+       );
+       /////////////////////
+       
+       // Public Variables
+       /////////////////////
+       
+       // Constructor
+       
+       /**
+     * Constructor for a style
+     * @param string $id The named style referenced by Excel.  This is called by
+     * ExcelWriterXML object when adding a style
+     */
+       function ExcelWriterXML_Style($id)
+       {
+               $this->id = $id;
+       }
+       /////////////////////
+       
+       /**
+        * Returns the named style for this style
+        * @return string $id The id for this style
+        */
+       function getID()
+       {
+               return $this->id;
+       }
+       
+       /**
+     * Retrieves the XML string data for a style.
+     * Called by ExcelWriterXML object
+     * @return string Returns the formatted XML data <style>...</style>
+     */
+       function getStyleXML()
+       {
+               $name = '';
+               $valign = '';
+               $halign = '';
+               $rotate = '';
+               $shrinktofit = '';
+               $verticaltext = '';
+               $wraptext = '';
+               
+               $bold = '';
+               $italic = '';
+               $strikethrough = '';
+               $underline = '';
+               $outline = '';
+               $shadow = '';
+               $fontName = '';
+               $fontFamily = '';
+               $fontSize = '';
+               
+               $borders = '';
+               
+               $interior = '';
+               $interiorColor = '';
+               $interiorPattern = '';
+               $interiorPatternColor = '';
+               
+               $numberFormat = '';
+               
+               if (empty($this->id)) 
+                       throw new exception;
+               if (!empty($this->name)){$name = 'ss:Name="'.$this->name.'"';}
+               
+               // Alignment
+               if ($this->useAlignment)
+               {
+                       if (!empty($this->valign)) {$valign = 'ss:Vertical="'.$this->valign.'"';}
+                       if (!empty($this->halign)) {$halign = 'ss:Horizontal="'.$this->halign.'"';}
+                       if (!empty($this->rotate)) {$rotate = 'ss:Rotate="'.$this->rotate.'"';}
+                       if (!empty($this->shinktofit)) {$shrinktofit = 'ss:ShrinkToFit="1"';}
+                       if (!empty($this->verticaltext)) {$verticaltext = 'ss:VerticalText="1"';}
+                       if (!empty($this->wraptext)) {$wraptext = 'ss:WrapText="1"';}
+               }
+               
+               // Font
+               if ($this->useFont)
+               {
+                       if (!empty($this->fontColor)) {$fontColor = 'ss:Color="'.$this->fontColor.'"';}
+                       if (!empty($this->bold)) {$bold = 'ss:Bold="1"';}
+                       if (!empty($this->italic)) {$italic = 'ss:Italic="1"';}
+                       if (!empty($this->strikethrough)) {$strikethrough = 'ss:StrikeThrough="'.$this->strikethrough.'"';}
+                       if (!empty($this->underline)) {$underline = 'ss:Underline="'.$this->underline.'"';}
+                       if (!empty($this->outline)) {$outline = 'ss:Outline="1"';}
+                       if (!empty($this->shadow)) {$shadow = 'ss:Shadow="1"';}
+                       if (!empty($this->fontName)) {$fontName = 'ss:FontName="'.$this->fontName.'"';}
+                       if (!empty($this->fontFamily)) {$fontFamily = 'x:Family="'.$this->fontFamily.'"';}
+                       if (!empty($this->fontSize)) {$fontSize = 'ss:Size="'.$this->fontSize.'"';}
+               }
+               // Border
+               if ($this->useBorder)
+               {
+                       $borders = '            <Borders>'."\r";
+                       $positions = array(
+                               'Top'                   => $this->borderTop,
+                               'Bottom'                => $this->borderBottom,
+                               'Left'                  => $this->borderLeft,
+                               'Right'                 => $this->borderRight,
+                               'DiagonalLeft'  => $this->borderDL,
+                               'DiagonalRight' => $this->borderDR,
+
+                       );
+                       foreach($positions as $position => $pData)
+                       {
+                               if (empty($pData)) 
+                                       continue;
+                               $bLinestyle = isset($pData['LineStyle'])
+                                       ? 'ss:LineStyle="'.$pData['LineStyle'].'"'
+                                       : '';
+                               $bColor = isset($pData['Color'])
+                                       ? 'ss:Color="'.$pData['Color'].'"'
+                                       : '';
+                               $bWeight = isset($pData['Weight'])
+                                       ? 'ss:Weight="'.$pData['Weight'].'"'
+                                       : '';
+                               $borders .= '                   <Border ss:Position="'.$position.'" '.$bLinestyle.' '.$bColor.' '.$bWeight.'/>'."\r";
+                       }
+                       $borders .= '           </Borders>'."\r";
+               }
+               
+               if ($this->useInterior)
+               {
+                       if (!empty($this->interiorColor)) {$interiorColor = 'ss:Color="'.$this->interiorColor.'"';}
+                       if (!empty($this->interiorPattern)) {$interiorPattern = 'ss:Pattern="'.$this->interiorPattern.'"';}
+                       if (!empty($this->interiorPatternColor)) {$interiorPatternColor = 'ss:PatternColor="'.$this->interiorPatternColor.'"';}
+                       $interior = '           <Interior '.$interiorColor.' '.$interiorPattern.' '.$interiorPatternColor.'/>'."\r";
+               }
+               
+               if (!empty($this->numberFormat)) 
+               {
+                       $numberFormat = '               <NumberFormat ss:Format="'.$this->numberFormat.'"/>'."\r";
+               }
+               else 
+                       $numberFormat = '               <NumberFormat/>'."\r";
+               
+               $xml = '        <Style ss:ID="'.$this->id.'" '.$name.'>'."\r";
+               if ($this->useAlignment) 
+                       $xml .= '               <Alignment '.$valign.' '.$halign.' '.$rotate.' '.$shrinktofit.' '.$wraptext.' '.$verticaltext.'/>'."\r";
+               if ($this->useBorder) 
+                       $xml .= $borders;
+               if ($this->useFont) 
+                       $xml .= '               <Font '.$fontSize.' '.$fontColor.' '.$bold.' '.$italic.' '.$strikethrough.' '.$underline.' '.$shadow.' '.$outline.' '.$fontName.' '.$fontFamily.'/>'."\r";
+               if ($this->useInterior) 
+                       $xml .= $interior;
+               $xml .= $numberFormat;
+               $xml .= '               <Protection/>'."\r";
+               $xml .= '       </Style>'."\r";
+               return($xml);
+       }
+       
+       /**
+        * Checks whether a color is valid for the spreadsheet
+        * @param string $color Named color from MS or web color in HEX format (e.g.
+     * #ff00ff
+     * @return mixed Either the valid color in HEX format or false if the color
+     * is not valid
+        */
+       function checkColor($color)
+       {
+               $pattern = "/[0-9a-f]{6}/";
+               if (preg_match($pattern, $color, $matches)) 
+               {
+                       $color = '#'.$matches[0];
+                       return($color);
+               }
+               elseif (isset($this->namedColorsIE[strtolower($color)]))
+               {
+                       $color = $this->namedColorsIE[strtolower($color)];
+                       return($color);
+               }
+               else
+               {
+                       $this->_addError(__FUNCTION__,'Supplied color was not valid "'.$color.'"');
+                       return(false);
+               }
+       }
+       
+       /**
+        * Adds a format error.  When the document is generated if there are any
+        * errors they will be listed on a seperate sheet.
+        * @param string $namedStyle The style in which the error occurred
+        * @param string $function The name of the function that was called
+        * @param string $message Details of the error
+        */
+       function _addError($function, $message)
+       {
+               $tmp = array(
+                       'style'         => $this->id,
+                       'function'      => $function,
+                       'message'       => $message,
+               );
+               $this->formatErrors[] = $tmp;
+       }
+
+       /**
+        * Returns any errors found in the sheet
+        * @return mixed Array of errors if they exist, otherwise false
+        */
+       function getErrors()
+       {
+               return($this->formatErrors);
+       }
+
+       
+       // Change Options
+       
+       /**
+     * Changes the name of the named style
+     * @param string $name The named style referenced by Excel.
+     */
+       function name($name) {$this->name = $name; }
+       ////////////////////////
+       
+       // Change Alignment
+       /**
+     * Changes the vertical alignment setting for the style
+     * @param string $valign The value for the vertical alignment.
+     * Acceptable values are "Automatic" "Top" "Bottom" "Center"
+     */
+       function alignVertical($valign)
+       {
+               // Automatic, Top, Bottom, Center
+               if ($valign != 'Automatic'
+                       && $valign != 'Top'
+                       && $valign != 'Bottom'
+                       && $valign != 'Center')
+               {
+                       $this->_addError(__FUNCTION__,'vertical alignment was not valid "'.$valign.'"');
+                       return;
+               }
+               $this->valign = $valign;
+               $this->useAlignment = true;
+       }
+       
+       /**
+     * Changes the horizontal alignment setting for the style
+     * @param string $halign The value for the horizontal alignment. Acceptable
+     * values are "Automatic" "Left" "Center" "Right"
+     */
+       function alignHorizontal($halign)
+       {
+               // Automatic, Left, Center, Right
+               if ($halign != 'Automatic'
+                       && $halign != 'Left'
+                       && $halign != 'Center'
+                       && $halign != 'Right')
+               {
+                       $this->_addError(__FUNCTION__,'horizontal alignment was not valid "'.$halign.'"');
+                       $halign = 'Automatic';
+               }
+               $this->halign = $halign;
+               $this->useAlignment = true;
+       }
+       
+       /**
+     * Changes the rotation setting for the style
+     * @param mixed $rotate The value for the Rotation.  Value must be a
+     * number between -90 and 90
+     */
+       function alignRotate($rotate)
+       {
+               // Degrees to rotate the text
+               if (!is_numeric($rotate))
+               {
+                       $this->_addError(__FUNCTION__,'rotation was not numeric "'.$rotate.'"');
+                       return;
+               }
+               if (abs($rotate) > 90)
+               {
+                       $rotate = $rotate % 90;
+                       $this->_addError(__FUNCTION__,'rotation was greater than 90, defaulted to "'.$rotate.'"');
+               }
+               $this->rotate = $rotate;
+               $this->useAlignment = true;
+       }
+       
+       /**
+     * Changes the Shrink To Fit setting for the style
+     * ShrinkToFit shrinks the text so that it fits within the cell.
+     * This doesn't actually work.
+     */
+       function alignShrinktofit()
+       {
+               $this->shrinktofit = 1;
+               $this->useAlignment = true;
+       }
+       
+       /**
+     * Changes the Vertical Text setting for the style.
+     * Text will be displayed vertically.
+     */
+       function alignVerticaltext()
+       {
+               $this->verticaltext = 1;
+               $this->useAlignment = true;
+       }
+       
+       /**
+     * Changes the Wrap Text setting for the style.
+     */
+       function alignWraptext()
+       {
+               $this->wraptext = 1;
+               $this->useAlignment = true;
+       }
+       /////////////////////////
+       
+       // Change Font
+       /**
+     * Changes the size of the font
+     * @param string $fontSize The value for the Size. Value must be greater
+     * than zero
+     */
+       function fontSize($fontSize = 10)
+       {
+               if (!is_numeric($fontSize))
+               {
+                       $fontSize = 10;
+                       $this->_addError(__FUNCTION__,'font size was not a number, defaulted to 10 "'.$fontSize.'"');
+               }
+               if ($fontSize <= 0)
+               {
+                       $fontSize = 10;
+                       $this->_addError(__FUNCTION__,'font size was less than zero, defaulted to 10 "'.$fontSize.'"');
+               }
+               $this->fontSize = $fontSize;
+               $this->useFont = true;
+       }
+       
+       /**
+     * Changes the color for the font
+     * @param string $fontColor The value for the Color.
+     * This can be a MS named color or a Hex web color.
+     */
+       function fontColor($fontColor = 'Automatic')
+       {
+               $pattern = "/[0-9a-f]{6}/";
+               $fontColor = $this->checkColor($fontColor);             
+               if ($fontColor === false)
+               {
+                       $this->_addError(__FUNCTION__,'font color was not valid "'.$fontColor.'"');
+                       $fontColor = 'Automatic';
+               }
+               $this->fontColor = $fontColor;
+               $this->useFont = true;
+       }
+       
+       /**
+     * Changes the font for the cell
+     * @param string $fontName The value for the font name. This should be a
+     * standard windows font available on most systems.
+     */
+       function fontName($fontName = 'Arial')
+       {
+               $this->fontName = $fontName;
+               $this->useFont = true;
+       }
+       
+       /**
+     * Changes the family for the font
+     * @param string $fontFamily The value for the font family. Not really sure
+     * what this does.
+     * Win32-dependant font family.
+     * Values can be "Automatic" "Decorative"
+     * "Modern" "Roman" "Script" "Swiss"
+     */
+       function fontFamily($fontFamily = 'Swiss')
+       {
+               // Win32-dependent font family.  
+               // Automatic, Decorative, Modern, Roman, Script, and Swiss 
+               if ($fontFamily != 'Automatic'
+                       && $fontFamily != 'Decorative'
+                       && $fontFamily != 'Modern'
+                       && $fontFamily != 'Roman'
+                       && $fontFamily != 'Script'
+                       && $fontFamily != 'Swiss')
+               {
+                       $this->_addError(__FUNCTION__,'font family was not valid "'.$fontFamily.'"');
+                       return;
+               }
+               $this->fontFamily = $fontFamily;
+               $this->useFont = true;
+       }
+       
+       /**
+     * Makes the font bold for the named style
+     */
+       function fontBold()
+       {
+               $this->bold = 1;
+               $this->useFont = true;
+       }
+       
+       /**
+     * Makes the font italic for the named style
+     */
+       function fontItalic()
+       {
+               $this->italic = 1;
+               $this->useFont = true;
+       }
+       
+       /**
+     * Makes the font strikethrough for the named style
+     */
+       function fontStrikethrough()
+       {
+               $this->strikethrough = 1;
+               $this->useFont = true;
+       }
+       
+       /**
+     * Makes the font underlined for the named style
+     * @param string $uStyle The type of underlining for the style.
+     * Acceptable values are "None" "Single" "Double" "SingleAccounting"
+     * "DoubleAccounting"
+     */
+       function fontUnderline($uStyle = 'Single')
+       {
+               // None, Single, Double, SingleAccounting, and DoubleAccounting
+               if ($uStyle != 'None'
+                       && $uStyle != 'Single'
+                       && $uStyle != 'Double'
+                       && $uStyle != 'SingleAccounting'
+                       && $uStyle != 'DoubleAccounting')
+               {
+                       $this->_addError(__FUNCTION__,'underline type was not valid "'.$uStyle.'"');
+                       return;
+               }
+               $this->underline = $uStyle;
+               $this->useFont = true;
+       }
+       
+       /**
+     * Makes the font shadowed for the named style
+     */
+       function fontShadow()
+       {
+               $this->shadow = 1;
+               $this->useFont = true;
+       }
+
+       /**
+     * Makes the font outlines for the named style
+     */
+       function fontOutline()
+       {
+               $this->outline = 1;
+               $this->useFont = true;
+       }
+       //////////////////////////
+       
+       // Change Border
+       
+       /**
+     * Sets the border for the named style.
+     * This function can be called multiple times to set different sides of the
+     * cell or set all sides the same at once.
+     * @param string $position Sets which side of the cell should be modified.
+     * Acceptable values are "All" "Left" "Top" "Right" "Bottom" "DiagonalLeft"
+     * "DiagonalRight"
+     * @param integer $weight Thickness of the border.  Default is 1 "Thin"
+     * @param string $color Color of the border. Default is "Automatic" but any
+     * 6-hexadecimal digit number in "#rrggbb" format or it can be any of the
+     * Microsoft® Internet Explorer named colors
+     * @param string $linestyle Type of line to use on the border.
+     * Default is "Continuous".  Acceptable balues are "None" "Continuous"
+     * "Dash" "Dot" "DashDot" "DashDotDot" "SlantDashDot" "Double"
+     */
+       function border(
+               $position = 'All'                       // All, Left, Top, Right, Bottom, DiagonalLeft, DiagonalRight
+               ,$weight = '1'                          // 0\97Hairline, 1\97Thin, 2\97Medium, 3\97Thick
+               ,$color = 'Automatic'           // Automatic, 6-hexadecimal digit number in "#rrggbb" format or it can be any of the Microsoft® Internet Explorer named colors
+               ,$linestyle = 'Continuous'      // None, Continuous, Dash, Dot, DashDot, DashDotDot, SlantDashDot, Double
+               )
+       {
+               if ($position != 'All'
+                       && $position != 'Left'
+                       && $position != 'Top'
+                       && $position != 'Right'
+                       && $position != 'Bottom'
+                       && $position != 'DiagonalLeft'
+                       && $position != 'DiagonalRight')
+               {
+                       $this->_addError(__FUNCTION__,'border position was not valid, defaulted to All "'.$position.'"');
+                       $position = 'All';
+               }
+               
+               if (is_numeric($weight))
+               {
+                       if (abs($weight) > 3)
+                       {
+                               $this->_addError(__FUNCTION__,'line weight greater than 3, defaulted to 3 "'.$weight.'"');
+                               $weight = 3;
+                       }
+               }
+               else
+               {
+                       $this->_addError(__FUNCTION__,'line weight not numeric, defaulted to 3 "'.$weight.'"');
+                       $weight = 1;
+               }
+
+               $color = $this->checkColor($color);             
+               if ($color === false)
+               {
+                       $this->_addError(__FUNCTION__,'border color was not valid, defaulted to Automatic "'.$weight.'"');
+                       $color = 'Automatic';
+               }
+
+               if ($linestyle != 'None'
+                       && $linestyle != 'Continuous'
+                       && $linestyle != 'Dash'
+                       && $linestyle != 'Dot'
+                       && $linestyle != 'DashDot'
+                       && $linestyle != 'DashDotDot'
+                       && $linestyle != 'SlantDashDot'
+                       && $linestyle != 'Double')
+               {
+                       $linestyle = 'Continuous';
+                       $this->_addError(__FUNCTION__,'line style was not valid, defaulted to Continuous "'.$linestyle.'"');
+               }
+
+               
+               $tmp = array(
+                       'LineStyle'     => $linestyle,
+                       'Color'         => $color,
+                       'Weight'        => $weight,
+               );
+               if ($position == 'Top'          || $position == 'All') $this->borderTop = $tmp;
+               if ($position == 'Bottom'       || $position == 'All') $this->borderBottom = $tmp;
+               if ($position == 'Left'         || $position == 'All') $this->borderLeft = $tmp;
+               if ($position == 'Right'        || $position == 'All') $this->borderRight = $tmp;
+               if ($position == 'DiagonalLeft' )                                       $this->borderDL = $tmp;
+               if ($position == 'DiagonalRight'        )                               $this->borderDR = $tmp;
+               
+               $this->useBorder = true;
+       }
+       //////////////////////////
+       
+       // Change Interior
+       /**
+     * Sets the background style of a style
+     * @param string $color Named color from MS or web color in HEX format (e.g.
+     * #ff00ff
+     * @param string $pattern Defaults to a None if not supplied.
+     * @param string $patternColor Defaults to a Automatic if not supplied.
+     */
+       function bgColor($color = 'Yellow',$pattern = 'Solid', $patternColor = null)
+       {
+               // 6-hexadecimal digit number in "#rrggbb" format
+               // Or it can be any of the Internet Explorer named colors
+               $color = $this->checkColor($color);
+               if ($color === false)
+               {
+                       $color = 'Yellow';
+                       $this->_addError(__FUNCTION__,'cell color not valid, defaulted to Yellow "'.$color.'"');
+               }
+               $this->interiorColor = $color;
+               if ($pattern != 'None')
+               {
+                       $this->bgPattern($pattern, $patternColor);
+               }
+               $this->useInterior = true;
+       }
+
+       /**
+     * Sets the background pattern of a style.
+     * @see bgColor()
+     * @param string $color Named color from MS or web color in HEX format (e.g.
+     * #ff00ff
+     * @param string $pattern Defaults to a solid if not supplied.
+     */
+       function bgPattern($pattern = 'None', $color = null)
+       {
+               // None, Solid, Gray75, Gray50, Gray25, Gray125, Gray0625,
+               // HorzStripe, VertStripe, ReverseDiagStripe, DiagStripe,
+               // DiagCross, ThickDiagCross, ThinHorzStripe, ThinVertStripe,
+               // ThinReverseDiagStripe, ThinDiagStripe, ThinHorzCross, and ThinDiagCross
+               if ($pattern != 'None'
+                       && $pattern != 'Solid'
+                       && $pattern != 'Gray75'
+                       && $pattern != 'Gray50'
+                       && $pattern != 'Gray25'
+                       && $pattern != 'Gray125'
+                       && $pattern != 'Gray0625'
+                       && $pattern != 'HorzStripe'
+                       && $pattern != 'VertStripe'
+                       && $pattern != 'ReverseDiagStripe'
+                       && $pattern != 'DiagStripe'
+                       && $pattern != 'DiagCross'
+                       && $pattern != 'ThickDiagCross'
+                       && $pattern != 'ThinHorzStripe'
+                       && $pattern != 'ThinVertStripe'
+                       && $pattern != 'ThinReverseDiagStripe'
+                       && $pattern != 'ThinDiagStripe'
+                       && $pattern != 'ThinHorzCross'
+                       && $pattern != 'ThinDiagCross')
+               {
+                       $pattern = 'None';
+                       $this->_addError(__FUNCTION__,'cell pattern was not valid, defaulted to Solid "'.$pattern.'"');
+               }
+
+               $this->interiorPattern = $pattern;
+               if ($color != null) 
+                       $this->bgPatternColor($color);
+               $this->useInterior = true;
+       }
+
+       /**
+     * Specifies the secondary fill color of the cell when Pattern does not equal Solid.
+     * @see function bgPattern()
+     * @param string $color Named color from MS or web color in HEX format (e.g.
+     * #ff00ff
+     * @param string $pattern Defaults to a solid if not supplied.
+     */
+       function bgPatternColor($color = 'Yellow')
+       {
+               // 6-hexadecimal digit number in "#rrggbb" format
+               // Or it can be any of the Internet Explorer named colors
+               if ($color != 'Automatic')
+               {
+                       $color = $this->checkColor($color);             
+                       if ($color === false)
+                       {
+                               $color = 'Automatic';
+                               $this->_addError(__FUNCTION__,'cell pattern color was not valid, defaulted to Automatic "'.$color.'"');
+                       }
+               }
+               $this->interiorPatternColor = $color;
+               $this->useInterior = true;
+       }
+
+       //////////////////////////
+       
+       // Number Formats
+
+       /**
+     * Sets the number format of a style
+     * @param string $formatString Format string to be used by Excel for
+     * displaying the number.
+     */
+       function numberFormat($formatString) { $this->numberFormat = $formatString; }
+
+       /**
+     * Sets a default date format for a style
+     */
+       function numberFormatDate($format=null) { $this->numberFormat($format==null?'mm/dd/yyyy':$format); }
+
+       /**
+     * Sets a default time format for a style
+     */
+       function numberFormatTime($format=null) { $this->numberFormat($format==null?'hh:mm:ss':$format); }
+
+       /**
+     * Sets a default date and time format for a style
+     */
+       function numberFormatDatetime($format=null) { $this->numberFormat($format==null?'mm/dd/yyyy\ hh:mm:ss':$format); }
+       //////////////////////////
+}
+?>
\ No newline at end of file
diff --git a/reporting/includes/excel_report.inc b/reporting/includes/excel_report.inc
new file mode 100644 (file)
index 0000000..603efb8
--- /dev/null
@@ -0,0 +1,389 @@
+<?php
+/**********************************************************************
+    Copyright (C) FrontAccounting, LLC.
+       Released under the terms of the GNU General Public License, GPL, 
+       as published by the Free Software Foundation, either version 3 
+       of the License, or (at your option) any later version.
+    This program 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 License here <http://www.gnu.org/licenses/gpl-3.0.html>.
+***********************************************************************/
+/* $Revision$ */
+$page_security = 8;
+include_once($path_to_root . "/reporting/includes/ExcelWriterXML.php");
+include_once($path_to_root . "/admin/db/company_db.inc");
+include_once($path_to_root . "/config.php");
+
+//class FrontReport extends ExcelWriterXML
+class FrontReport
+{
+       var $xml;
+       var $size;
+       var $company;
+       var $user;
+       var $host;
+       var $fiscal_year;
+       var $title;
+       var $filename;
+       var $path;
+       var $lineHeight;
+       var $rtl;
+       var $code;
+       var $bottomMargin = 0;
+
+       var $cols;
+       var $params;
+       var $headers;
+       var $aligns;
+       var $headers2;
+       var $aligns2;
+       var $cols2;
+       var $fontSize;
+       var $oldFontSize;
+       var $currency;
+       var $row = 9999999;
+       var $y;
+       
+       var $sheet;
+       var $formatTitle;
+       var $formatDateTime;
+       var $formatDate;
+       var $formatRight;
+       var $formatHeaderLeft;
+       var $formatHeaderRight;
+       var $formatAmount = array();
+       var $formatFooter;
+
+       function FrontReport($title, $filename, $size = 'A4', $fontsize = 9)
+       {
+               global $comp_path, $dateseps, $thoseps, $decseps;
+               
+               $this->size = $size;
+               $this->title = $title;
+               $this->lineHeight = 12;
+               $this->fontSize = $fontsize;
+               $this->oldFontSize = 0;
+               $this->y = 1;
+               $this->currency = '';
+               $this->rtl = ($_SESSION['language']->dir === 'rtl' ? 'rtl' : 'ltr');
+               $this->code = $_SESSION['language']->encoding;
+               $this->filename = $filename;
+               $this->path = $comp_path.'/'.user_company(). '/pdf_files/';
+               //$this->ExcelWriterXML($this->filename);
+               $this->xml = new ExcelWriterXML($this->filename);
+               $this->xml->setCharSet($this->code);
+               $this->xml->overwriteFile();
+               $this->xml->showErrorSheet(true);
+               $this->sheet = $this->xml->addSheet($this->title);
+               if ($this->rtl === 'rtl')
+                       $this->sheet->displayRightToLeft();
+               $this->formatTitle = $this->xml->addStyle('formatTitle');       
+               $this->formatTitle->fontSize('18');
+               $this->formatTitle->fontBold();
+               $this->formatTitle->border('Top', '2', 'darkgray');
+       
+               $how = user_date_format();
+               $sep = $dateseps[user_date_sep()];
+               if ($sep == '.')
+                       $sep = "\\.";
+               if ($how == 0)
+               {
+                       $dateformat_long = "mm{$sep}dd{$sep}yyyy\ \ hh:mm\ am/pm";
+                       $dateformat = "mm{$sep}dd{$sep}yyyy";
+               }       
+               elseif ($how == 1)      
+               {
+                       $dateformat_long = "dd{$sep}mm{$sep}yyyy\ \ hh:mm";
+                       $dateformat = "dd{$sep}mm{$sep}yyyy";
+               }       
+               else    
+               {
+                       $dateformat_long = "yyyy{$sep}mm{$sep}dd\ \ hh:mm";
+                       $dateformat = "yyyy{$sep}mm{$sep}dd";
+               }       
+               $this->formatDateTime = $this->xml->addStyle('formatDateTime');
+               $this->formatDateTime->numberFormatDateTime($dateformat_long);
+               $this->formatDateTime->alignHorizontal('Left');
+               $this->formatDate = $this->xml->addStyle('formatDate');
+               $this->formatDate->numberFormatDateTime($dateformat);
+               $this->formatDate->alignHorizontal('Left');
+               $this->formatRight = $this->xml->addStyle('formatRight');
+               $this->formatRight->alignHorizontal('Right');
+               
+               $this->formatHeaderLeft = $this->xml->addStyle("formatHeaderLeft");
+               $this->formatHeaderLeft->fontItalic();
+               $this->formatHeaderLeft->border('Top', '2', 'darkgray');
+               $this->formatHeaderLeft->border('Bottom', '2', 'darkgray');
+               $this->formatHeaderLeft->alignVertical('Center');
+               $this->formatHeaderRight = $this->xml->addStyle("formatHeaderRight");
+               $this->formatHeaderRight->fontItalic();
+               $this->formatHeaderRight->alignHorizontal('Right');
+               $this->formatHeaderRight->border('Top', '2', 'darkgray');
+               $this->formatHeaderRight->border('Bottom', '2', 'darkgray');
+               $this->formatHeaderRight->alignVertical('Center');
+               $tsep = $thoseps[user_tho_sep()];
+               $dsep = $decseps[user_dec_sep()];
+               $amountformat = "###{$tsep}###{$tsep}###{$tsep}##0";
+               $this->formatAmount[0] = $this->xml->addStyle("formatAmount0");
+               $this->formatAmount[0]->numberFormat($amountformat);
+               $this->formatAmount[0]->alignHorizontal('Right');
+               $this->formatAmount[1] = $this->xml->addStyle("formatAmount1");
+               $this->formatAmount[1]->numberFormat("$amountformat{$dsep}0");
+               $this->formatAmount[1]->alignHorizontal('Right');
+               $this->formatAmount[2] = $this->xml->addStyle("formatAmount2");
+               $this->formatAmount[2]->numberFormat("$amountformat{$dsep}00");
+               $this->formatAmount[2]->alignHorizontal('Right');
+               $this->formatAmount[3] = $this->xml->addStyle("formatAmount3");
+               $this->formatAmount[3]->numberFormat("$amountformat{$dsep}000");
+               $this->formatAmount[3]->alignHorizontal('Right');
+               $this->formatAmount[4] = $this->xml->addStyle("formatAmount4");
+               $this->formatAmount[4]->numberFormat("$amountformat{$dsep}0000");
+               $this->formatAmount[4]->alignHorizontal('Right');
+               $this->formatFooter = $this->xml->addStyle("formatFooter");
+               $this->formatFooter->border('Top', '2', 'darkgray');
+       }
+
+       function Font($style = 'normal')
+       {
+       }
+
+       function Info($params, $cols, $headers, $aligns,
+               $cols2 = null, $headers2 = null, $aligns2 = null)
+       {
+               global $app_title, $version, $power_by, $power_url;
+
+               $this->company = get_company_prefs();
+               $this->xml->docTitle($this->title);
+               $this->xml->docAuthor($app_title . ' ' . $version);
+               $this->xml->docCompany($this->company['coy_name']);
+               $this->xml->docManager($power_by . ' - ' . $power_url);
+               $year = get_current_fiscalyear();
+               if ($year['closed'] == 0)
+                       $how = _("Active");
+               else
+                       $how = _("Closed");
+               $this->fiscal_year = sql2date($year['begin']) . " - " . sql2date($year['end']) . "  " . "(" . $how . ")";
+               $this->user = $_SESSION["wa_current_user"]->name;
+               $this->host = $_SERVER['SERVER_NAME'];
+               $this->params = $params;
+               $this->cols = $cols;
+               $this->headers = $headers;
+               $this->aligns = $aligns;
+               $this->cols2 = $cols2;
+               $this->headers2 = $headers2;
+               $this->aligns2 = $aligns2;
+               for ($i = 0; $i < count($this->headers); $i++)
+                       $this->sheet->columnWidth($i+1, $this->cols[$i + 1] - $this->cols[$i]);
+       }
+
+       function Header()
+       {
+               $this->y = 0;
+               $this->NewLine();
+               $this->sheet->rowHeight($this->y, 22);
+               $this->sheet->writeString($this->y, 1, $this->title, $this->formatTitle);
+               $this->sheet->cellMerge($this->y, 1, count($this->headers)-1, 0);
+
+               $this->NewLine();
+
+               $str = _("Print Out Date") . ':';
+               $this->sheet->writeString($this->y, 1, $str);
+               $date = $this->sheet->convertMysqlDateTime(date('Y-m-d h:i:s'));
+               $this->sheet->writeDateTime($this->y, 2, $date, $this->formatDateTime);
+               $this->sheet->writeString($this->y, 4, $this->company['coy_name']);
+               $this->sheet->cellMerge($this->y, 4, 1, 0);
+               $this->NewLine();
+               $str = _("Fiscal Year") . ':';
+               $this->sheet->writeString($this->y, 1, $str);
+               $str = $this->fiscal_year;
+               $this->sheet->writeString($this->y, 2, $str);
+               $this->sheet->writeString($this->y, 4, $this->host);
+               $this->sheet->cellMerge($this->y, 4, 1, 0);
+               for ($i = 1; $i < count($this->params); $i++)
+               {
+                       if ($this->params[$i]['from'] != '')
+                       {
+                               $this->NewLine();
+                               $str = $this->params[$i]['text'] . ':';
+                               $this->sheet->writeString($this->y, 1, $str);
+                               $str = $this->params[$i]['from'];
+                               if ($this->params[$i]['to'] != '')
+                                       $str .= " - " . $this->params[$i]['to'];
+                               $this->sheet->writeString($this->y, 2, $str);
+                               if ($i == 1)
+                               {
+                                       $this->sheet->writeString($this->y, 4, $this->user);
+                                       $this->sheet->cellMerge($this->y, 4, 1, 0);
+                               }       
+                       }
+               }
+               if ($this->params[0] != '') // Comments
+               {
+                       $this->NewLine();
+                       $str = _("Comments") . ':';
+                       $this->sheet->writeString($this->y, 1, $str);
+                       $this->sheet->writeString($this->y, 2, $this->params[0]);
+               }
+               $this->NewLine();
+               if ($this->headers2 != null)
+               {
+                       $count = count($this->headers2);
+                       for ($i = 0; $i < $count; $i++)
+                       {
+                               if ($this->aligns2[$i] == "right")
+                                       $this->sheet->writeString($this->y, $i + 1, $this->headers2[$i], $this->formatHeaderRight);
+                               else    
+                                       $this->sheet->writeString($this->y, $i + 1, $this->headers2[$i], $this->formatHeaderLeft);
+                       }               
+                       $this->NewLine();
+               }
+
+               $count = count($this->headers);
+               for ($i = 0; $i < $count; $i++)
+               {
+                       if ($this->aligns[$i] == "right")
+                               $this->sheet->writeString($this->y, $i + 1, $this->headers[$i], $this->formatHeaderRight);
+                       else    
+                               $this->sheet->writeString($this->y, $i + 1, $this->headers[$i], $this->formatHeaderLeft);
+               }               
+               $this->NewLine();
+       }
+
+       function Header2($myrow, $branch, $sales_order, $bankaccount, $doctype)
+       {
+               return;
+       }
+
+       function AddImage($logo, $x, $y, $w, $h)
+       {
+               return;
+       }
+
+       function SetDrawColor($r, $g, $b)
+       {
+               return;
+       }
+
+       function SetTextColor($r, $g, $b)
+       {
+               return;
+       }
+
+       function Text($c, $txt, $n=0, $corr=0, $r=0)
+       {
+               return;
+       }
+
+       function TextWrap($xpos, $ypos, $len, $str, $align = 'left')
+       {
+               return;
+       }
+
+       function TextCol($c, $n, $txt, $corr=0, $r=0)
+       {
+               if ($this->aligns[$c] == 'right')
+                       $this->sheet->writeString($this->y, $c + 1, $txt, $this->formatRight);
+               else    
+                       $this->sheet->writeString($this->y, $c + 1, $txt);
+               if ($n - $c > 1)
+                       $this->sheet->cellMerge($this->y, $c + 1, $n - $c - 1, 0);
+       }
+
+       function AmountCol($c, $n, $txt, $dec=0, $corr=0, $r=0) 
+       { 
+               if (!is_numeric($txt))
+                       $txt = 0;
+               $this->sheet->writeNumber($this->y, $c + 1, $txt, $this->formatAmount[$dec]); 
+       }
+       
+       function DateCol($c, $n, $txt, $conv=false, $corr=0, $r=0) 
+       {
+               if (!$conv)
+                       $txt = date2sql($txt);
+               $date = $this->sheet->convertMysqlDate($txt);
+               $this->sheet->writeDate($this->y, $c + 1, $date, $this->formatDate);
+       }
+
+       function TextCol2($c, $n, $txt, $corr=0, $r=0)
+       {
+               $this->sheet->writeString($this->y, $c + 1, $txt);
+               if ($n - $c > 1)
+                       $this->sheet->cellMerge($this->y, $c + 1, $n - $c - 1, 0);
+       }
+
+       function TextColLines($c, $n, $txt, $corr=0, $r=0)
+       {
+               return;
+       }
+
+       function TextWrapLines($c, $width, $txt, $align='left')
+       {
+               return;
+       }
+
+       function LineTo($from, $row, $to, $row2)
+       {
+               return;
+       }
+
+       function Line($row, $height = 0)
+       {
+               return;
+       }
+
+       function NewLine($l=1, $np=0)
+       {
+               $this->y += $l;
+       }
+
+       function End($email=0, $subject=null, $myrow=null, $doctype = 0)
+       {
+               global $comp_path;
+               $this->sheet->cellMerge($this->y, 1, count($this->headers) - 1, 0);
+               $this->sheet->writeString($this->y, 1, "", $this->formatFooter);
+               
+               $dir =  $comp_path.'/'.user_company(). '/pdf_files';
+               //save the file
+               if (!file_exists($dir))
+               {
+                       mkdir ($dir,0777);
+               }
+               // do not use standard filenames or your sensitive company data 
+               // are world readable
+               //$fname = $dir.'/'.uniqid('').'.xml';
+               $fname = $dir.'/'."test".'.xml';
+               $this->xml->writeData($fname);
+               if(in_ajax()) 
+               {
+                       global $Ajax;
+                       if (user_rep_popup()) 
+                               $Ajax->popup($fname); // when embeded pdf viewer used
+                       else
+                               $Ajax->redirect($fname); // otherwise use faster method
+               } 
+               else 
+               {
+                       $this->xml->sendHeaders();
+                       $this->xml->writeData();
+               }       
+               // first have a look through the directory, 
+               // and remove old temporary pdfs
+               /*
+               if ($d = @opendir($dir)) {
+                       while (($file = readdir($d)) !== false) {
+                               if (!is_file($dir.'/'.$file) || $file == 'index.php') continue;
+                       // then check to see if this one is too old
+                               $ftime = filemtime($dir.'/'.$file);
+                        // seems 3 min is enough for any report download, isn't it?
+                               if (time()-$ftime > 180){
+                                       unlink($dir.'/'.$file);
+                               }
+                       }
+                       closedir($d);
+               }
+               */
+       }
+}
+
+?>
\ No newline at end of file
index fde0b441cdd8957286bfef2d9ad59c9dfdd30e81..ccf67123d5122db7f144d42fcef80595b24e797f 100644 (file)
@@ -319,6 +319,18 @@ class FrontReport extends Cpdf
        {
                return $this->TextWrap($this->cols[$c], $this->row - $r, $this->cols[$n] - $this->cols[$c] + $corr, $txt, $this->aligns[$c]);
        }
+       
+       function AmountCol($c, $n, $txt, $dec=0, $corr=0, $r=0)
+       {
+               return $this->TextCol($c, $n, number_format2($txt, $dec), $corr, $r);
+       }
+
+       function DateCol($c, $n, $txt, $conv=false, $corr=0, $r=0)
+       {
+               if ($conv)
+                       $txt = sql2date($txt);
+               return $this->TextCol($c, $n, $txt, $corr, $r);
+       }
 
        function TextCol2($c, $n, $txt, $corr=0, $r=0)
        {
index 98e58324b462380499f0cbe16914ac7693dec1f8..363e2284ad8015593a45621d38ef865af714abf7 100644 (file)
@@ -180,6 +180,10 @@ class Report
                                        $sel = array(_("No Payment Link"), "PayPal");
                                        $st .= dup_simple_name_list("PARAM_$index", $sel);
                                        break;
+                               case 'DESTINATION':
+                                       $sel = array(_("PDF/Printer"), "Excel");
+                                       $st .= dup_simple_name_list("PARAM_$index", $sel);
+                                       break;
                                case 'COMPARE':
                                        $sel = array(_("Accumulated"), _("Period Y-1"), _("Budget"));
                                        $st .= dup_simple_name_list("PARAM_$index", $sel);
index a0e7600fef528778c31ff94e9d3cc8648c7ff2fd..12bea194cccc7c882f880bb5838641a37a1a4f83 100644 (file)
@@ -34,10 +34,19 @@ function print_Chart_of_Accounts()
 {
        global $path_to_root;
 
-       include_once($path_to_root . "/reporting/includes/pdf_report.inc");
-
        $showbalance = $_POST['PARAM_0'];
        $comments = $_POST['PARAM_1'];
+       $destination = $_POST['PARAM_2'];
+       if (isset($destination) && $destination)
+       {
+               include_once($path_to_root . "/reporting/includes/excel_report.inc");
+               $filename = "ChartOfAccounts.xml";
+       }       
+       else
+       {
+               include_once($path_to_root . "/reporting/includes/pdf_report.inc");
+               $filename = "ChartOfAccounts.pdf";
+       }
        $dec = 0;
 
        $cols = array(0, 50, 300, 425, 500);
@@ -48,7 +57,7 @@ function print_Chart_of_Accounts()
        
        $params = array(0 => $comments);
 
-       $rep = new FrontReport(_('Chart of Accounts'), "ChartOfAccounts.pdf", user_pagesize());
+       $rep = new FrontReport(_('Chart of Accounts'), $filename, user_pagesize());
        
        $rep->Font();
        $rep->Info($params, $cols, $headers, $aligns);
@@ -77,12 +86,14 @@ function print_Chart_of_Accounts()
                                $rep->Font('bold');
                                $rep->TextCol(0, 4, $account['AccountClassName']);
                                $rep->Font();
-                               $rep->row -= ($rep->lineHeight + 4);
+                               //$rep->row -= ($rep->lineHeight + 4);
+                               $rep->NewLine();
                        }
                        $group = $account['AccountTypeName'];
                        $rep->TextCol(0, 4, $account['AccountTypeName']);
                        //$rep->Line($rep->row - 4);
-                       $rep->row -= ($rep->lineHeight + 4);
+                       //$rep->row -= ($rep->lineHeight + 4);
+                       $rep->NewLine();
                }
                $classname = $account['AccountClassName'];
 
@@ -90,7 +101,7 @@ function print_Chart_of_Accounts()
                $rep->TextCol(1, 2,     $account['account_name']);
                $rep->TextCol(2, 3,     $account['account_code2']);
                if ($showbalance == 1)  
-                       $rep->TextCol(3, 4,     number_format2($balance, $dec));
+                       $rep->AmountCol(3, 4, $balance, $dec);
 
                $rep->NewLine();
                if ($rep->row < $rep->bottomMargin + 3 * $rep->lineHeight)
index 6942d72d8c38c9241d9c47c0e53539108beced69..9d90a569122585ddac6226aacdd375bad75260ef 100644 (file)
@@ -81,7 +81,6 @@ function print_annual_expense_breakdown()
 {
        global $path_to_root, $date_system;
 
-       include_once($path_to_root . "/reporting/includes/pdf_report.inc");
        $dim = get_company_pref('use_dimension');
        $dimension = $dimension2 = 0;
 
@@ -91,17 +90,30 @@ function print_annual_expense_breakdown()
                $dimension = $_POST['PARAM_1'];
                $dimension2 = $_POST['PARAM_2'];
                $comments = $_POST['PARAM_3'];
+               $destination = $_POST['PARAM_4'];
        }
        else if ($dim == 1)
        {
                $year = $_POST['PARAM_0'];
                $dimension = $_POST['PARAM_1'];
                $comments = $_POST['PARAM_2'];
+               $destination = $_POST['PARAM_3'];
        }
        else
        {
                $year = $_POST['PARAM_0'];
                $comments = $_POST['PARAM_1'];
+               $destination = $_POST['PARAM_2'];
+       }
+       if (isset($destination) && $destination)
+       {
+               include_once($path_to_root . "/reporting/includes/excel_report.inc");
+               $filename = "AnnualBreakDown.xml";
+       }       
+       else
+       {
+               include_once($path_to_root . "/reporting/includes/pdf_report.inc");
+               $filename = "AnnualBreakDown.pdf";
        }
        $dec = 1;
        //$pdec = user_percent_dec();
@@ -169,7 +181,7 @@ function print_annual_expense_breakdown()
                                'to' => ''));
     }
 
-       $rep = new FrontReport(_('Annual Expense Breakdown'), "AnnualBreakDown.pdf", user_pagesize());
+       $rep = new FrontReport(_('Annual Expense Breakdown'), $filename, user_pagesize());
 
        $rep->Font();
        $rep->Info($params, $cols, $headers, $aligns);
@@ -205,27 +217,29 @@ function print_annual_expense_breakdown()
                {
                        if ($group != '')
                        {
-                               $rep->Line($rep->row + 6);
-                               $rep->row -= 6;
+                               $rep->row += 6;
+                               $rep->Line($rep->row);
+                               $rep->NewLine();
                                $rep->TextCol(0, 2,     _('Total') . " " . $group);
                                for ($i = 1; $i <= 12; $i++)
-                                       $rep->TextCol($i + 1, $i + 2, number_format2($total[$i], $dec));
+                                       $rep->AmountCol($i + 1, $i + 2, $total[$i], $dec);
                                $total = Array(1 => 0,0,0,0,0,0,0,0,0,0,0,0);
-                               $rep->row -= ($rep->lineHeight + 4);
+                               $rep->NewLine();
                                if ($closeclass)
                                {
-                                       $rep->Line($rep->row + 6);
-                                       $rep->row -= 6;
+                                       $rep->row += 6;
+                                       $rep->Line($rep->row);
+                                       $rep->NewLine();
                                        $rep->Font('bold');
                                        $rep->TextCol(0, 2,     _('Total') . " " . $classname);
                                        for ($i = 1; $i <= 12; $i++)
                                        {
-                                               $rep->TextCol($i + 1, $i + 2, number_format2($total2[$i], $dec));
+                                               $rep->AmountCol($i + 1, $i + 2, $total2[$i], $dec);
                                                $sales[$i] += $total2[$i];
                                        }
                                        $rep->Font();
                                        $total2 = Array(1 => 0,0,0,0,0,0,0,0,0,0,0,0);
-                                       $rep->NewLine(3);
+                                       $rep->NewLine(2);
                                        $closeclass = false;
                                }
                        }
@@ -234,19 +248,21 @@ function print_annual_expense_breakdown()
                                $rep->Font('bold');
                                $rep->TextCol(0, 5, $account['AccountClassName']);
                                $rep->Font();
-                               $rep->row -= ($rep->lineHeight + 4);
+                               $rep->NewLine();
                        }
                        $group = $account['AccountTypeName'];
+                       $rep->row -= 4;
                        $rep->TextCol(0, 5, $account['AccountTypeName']);
-                       $rep->Line($rep->row - 4);
-                       $rep->row -= ($rep->lineHeight + 4);
+                       $rep->row -= 4;
+                       $rep->Line($rep->row);
+                       $rep->NewLine();
                }
                $classname = $account['AccountClassName'];
                $rep->TextCol(0, 1,     $account['account_code']);
                $rep->TextCol(1, 2,     $account['account_name']);
                for ($i = 1; $i <= 12; $i++)
                {
-                       $rep->TextCol($i + 1, $i + 2, number_format2($balance[$i], $dec));
+                       $rep->AmountCol($i + 1, $i + 2, $balance[$i], $dec);
                        $total[$i] += $balance[$i];
                        $total2[$i] += $balance[$i];
                }
@@ -270,29 +286,31 @@ function print_annual_expense_breakdown()
        {
                if ($group != '')
                {
-                       $rep->Line($rep->row + 6);
-                       $rep->row -= 6;
+                       $rep->row += 6;
+                       $rep->Line($rep->row);
+                       $rep->NewLine();
                        $rep->TextCol(0, 2,     _('Total') . " " . $group);
                        for ($i = 1; $i <= 12; $i++)
-                               $rep->TextCol($i + 1, $i + 2, number_format2($total[$i], $dec));
-                       $rep->row -= ($rep->lineHeight + 4);
+                               $rep->AmountCol($i + 1, $i + 2, $total[$i], $dec);
+                       $rep->NewLine();
                        if ($closeclass)
                        {
-                               $rep->Line($rep->row + 6);
-                               $rep->row -= 6;
+                               $rep->row += 6;
+                               $rep->Line($rep->row);
+                               $rep->NewLine();
 
                                $rep->Font('bold');
                                $rep->TextCol(0, 2,     _('Total') . " " . $classname);
                                for ($i = 1; $i <= 12; $i++)
                                {
-                                       $rep->TextCol($i + 1, $i + 2, number_format2($total2[$i], $dec));
+                                       $rep->AmountCol($i + 1, $i + 2, $total2[$i], $dec);
                                        $calc[$i] = $sales[$i] + $total2[$i];
                                }
 
-                               $rep->row -= ($rep->lineHeight + 8);
+                               $rep->NewLine(2);
                                $rep->TextCol(0, 2,     _('Calculated Return'));
                                for ($i = 1; $i <= 12; $i++)
-                                       $rep->TextCol($i + 1, $i + 2, number_format2($calc[$i], $dec));
+                                       $rep->AmountCol($i + 1, $i + 2, $calc[$i], $dec);
                                $rep->Font();
 
                                $rep->NewLine();
index 0788363a2531648469e40b858644f1bd178897c6..e2ceaf35fa87cec53ae63a538c666e4916d0eced 100644 (file)
@@ -35,7 +35,6 @@ function print_balance_sheet()
 {
        global $comp_path, $path_to_root;
 
-       include_once($path_to_root . "/reporting/includes/pdf_report.inc");
        $dim = get_company_pref('use_dimension');
        $dimension = $dimension2 = 0;
 
@@ -47,17 +46,30 @@ function print_balance_sheet()
                $dimension2 = $_POST['PARAM_3'];
                $graphics = $_POST['PARAM_4'];
                $comments = $_POST['PARAM_5'];
+               $destination = $_POST['PARAM_6'];
        }
        else if ($dim == 1)
        {
                $dimension = $_POST['PARAM_2'];
                $graphics = $_POST['PARAM_3'];
                $comments = $_POST['PARAM_4'];
+               $destination = $_POST['PARAM_5'];
        }
        else
        {
                $graphics = $_POST['PARAM_2'];
                $comments = $_POST['PARAM_3'];
+               $destination = $_POST['PARAM_4'];
+       }
+       if (isset($destination) && $destination)
+       {
+               include_once($path_to_root . "/reporting/includes/excel_report.inc");
+               $filename = "BalanceSheet.xml";
+       }       
+       else
+       {
+               include_once($path_to_root . "/reporting/includes/pdf_report.inc");
+               $filename = "BalanceSheet.pdf";
        }
        if ($graphics)
        {
@@ -95,13 +107,12 @@ function print_balance_sheet()
        $params =   array(      0 => $comments,
                                    1 => array('text' => _('Period'),'from' => $from, 'to' => $to));
     }
+       //display_error("Error!");
 
-       $rep = new FrontReport(_('Balance Sheet'), "BalanceSheet.pdf", user_pagesize());
-
+       $rep = new FrontReport(_('Balance Sheet'), $filename, user_pagesize());
        $rep->Font();
        $rep->Info($params, $cols, $headers, $aligns);
        $rep->Header();
-
        $classname = '';
        $group = '';
        $totalopen = 0.0;
@@ -114,6 +125,7 @@ function print_balance_sheet()
        $assetsperiod = 0.0;
        $assetsclose = 0.0;
        $closeclass = false;
+       $rep->NewLine();
 
        $accounts = get_gl_accounts_all(1);
 
@@ -138,34 +150,36 @@ function print_balance_sheet()
                {
                        if ($group != '')
                        {
-                               $rep->Line($rep->row + 6);
-                               $rep->row -= 6;
+                               $rep->row += 6;
+                               $rep->Line($rep->row);
+                               $rep->NewLine();
                                $rep->TextCol(0, 2,     _('Total') . " " . $group);
-                               $rep->TextCol(2, 3,     number_format2($totalopen, $dec));
-                               $rep->TextCol(3, 4,     number_format2($totalperiod, $dec));
-                               $rep->TextCol(4, 5,     number_format2($totalclose, $dec));
+                               $rep->AmountCol(2, 3, $totalopen, $dec);
+                               $rep->AmountCol(3, 4, $totalperiod, $dec);
+                               $rep->AmountCol(4, 5, $totalclose, $dec);
                                if ($graphics)
                                {
                                        $pg->x[] = $group;
                                        $pg->y[] = abs($totalclose);
                                }
                                $totalopen = $totalperiod = $totalclose = 0.0;
-                               $rep->row -= ($rep->lineHeight + 4);
+                               $rep->NewLine();
                                if ($closeclass)
                                {
-                                       $rep->Line($rep->row + 6);
-                                       $rep->row -= 6;
+                                       $rep->row += 6;
+                                       $rep->Line($rep->row);
+                                       $rep->NewLine();
                                        $rep->Font('bold');
-                                       $rep->TextCol(0, 2,     _('Total') . " " . $classname);
-                                       $rep->TextCol(2, 3,     number_format2($classopen, $dec));
-                                       $rep->TextCol(3, 4,     number_format2($classperiod, $dec));
-                                       $rep->TextCol(4, 5,     number_format2($classclose, $dec));
+                                       $rep->TextCol(0, 2,     _('Total') . " " . $classname);
+                                       $rep->AmountCol(2, 3, $classopen, $dec);
+                                       $rep->AmountCol(3, 4, $classperiod, $dec);
+                                       $rep->AmountCol(4, 5, $classclose, $dec);
                                        $rep->Font();
                                        $assetsopen += $classopen;
                                        $assetsperiod += $classperiod;
                                        $assetsclose += $classclose;
                                        $classopen = $classperiod = $classclose = 0.0;
-                                       $rep->NewLine(3);
+                                       $rep->NewLine(2);
                                        $closeclass = false;
                                }
                        }
@@ -174,12 +188,14 @@ function print_balance_sheet()
                                $rep->Font('bold');
                                $rep->TextCol(0, 5, $account['AccountClassName']);
                                $rep->Font();
-                               $rep->row -= ($rep->lineHeight + 4);
+                               $rep->NewLine();
                        }
                        $group = $account['AccountTypeName'];
+                       $rep->row -= 4;
                        $rep->TextCol(0, 5, $account['AccountTypeName']);
-                       $rep->Line($rep->row - 4);
-                       $rep->row -= ($rep->lineHeight + 4);
+                       $rep->row -= 4;
+                       $rep->Line($rep->row);
+                       $rep->NewLine();
                }
                $classname = $account['AccountClassName'];
 
@@ -192,9 +208,9 @@ function print_balance_sheet()
                $rep->TextCol(0, 1,     $account['account_code']);
                $rep->TextCol(1, 2,     $account['account_name']);
 
-               $rep->TextCol(2, 3,     number_format2($prev_balance, $dec));
-               $rep->TextCol(3, 4,     number_format2($curr_balance, $dec));
-               $rep->TextCol(4, 5,     number_format2($curr_balance + $prev_balance, $dec));
+               $rep->AmountCol(2, 3, $prev_balance, $dec);
+               $rep->AmountCol(3, 4, $curr_balance, $dec);
+               $rep->AmountCol(4, 5, $curr_balance + $prev_balance, $dec);
 
                $rep->NewLine();
 
@@ -215,42 +231,42 @@ function print_balance_sheet()
        {
                if ($group != '')
                {
-                       $rep->Line($rep->row + 6);
-                       $rep->row -= 6;
+                       $rep->row += 6;
+                       $rep->Line($rep->row);
+                       $rep->NewLine();
                        $rep->TextCol(0, 2,     _('Total') . " " . $group);
-                       $rep->TextCol(2, 3,     number_format2($totalopen, $dec));
-                       $rep->TextCol(3, 4,     number_format2($totalperiod, $dec));
-                       $rep->TextCol(4, 5,     number_format2($totalclose, $dec));
+                       $rep->AmountCol(2, 3, $totalopen, $dec);
+                       $rep->AmountCol(3, 4, $totalperiod, $dec);
+                       $rep->AmountCol(4, 5, $totalclose, $dec);
                        if ($graphics)
                        {
                                $pg->x[] = $group;
                                $pg->y[] = abs($totalclose);
                        }
-                       $rep->row -= ($rep->lineHeight + 4);
+                       $rep->NewLine();
                        if ($closeclass)
                        {
-                               $rep->Line($rep->row + 6);
                                $calculateopen = -$assetsopen - $classopen;
                                $calculateperiod = -$assetsperiod - $classperiod;
                                $calculateclose = -$assetsclose  - $classclose;
-                               $rep->row -= 6;
-
+                               $rep->row += 6;
+                               $rep->Line($rep->row);
+                               $rep->NewLine();
                                $rep->TextCol(0, 2,     _('Calculated Return'));
-                               $rep->TextCol(2, 3,     number_format2($calculateopen, $dec));
-                               $rep->TextCol(3, 4,     number_format2($calculateperiod, $dec));
-                               $rep->TextCol(4, 5,     number_format2($calculateclose, $dec));
+                               $rep->AmountCol(2, 3, $calculateopen, $dec);
+                               $rep->AmountCol(3, 4, $calculateperiod, $dec);
+                               $rep->AmountCol(4, 5, $calculateclose, $dec);
                                if ($graphics)
                                {
                                        $pg->x[] = _('Calculated Return');
                                        $pg->y[] = abs($calculateclose);
                                }
-                               $rep->row -= ($rep->lineHeight + 4);
-
+                               $rep->NewLine(2);
                                $rep->Font('bold');
                                $rep->TextCol(0, 2,     _('Total') . " " . $classname);
-                               $rep->TextCol(2, 3,     number_format2(-$assetsopen, $dec));
-                               $rep->TextCol(3, 4,     number_format2(-$assetsperiod, $dec));
-                               $rep->TextCol(4, 5,     number_format2(-$assetsclose, $dec));
+                               $rep->AmountCol(2, 3, -$assetsopen, $dec);
+                               $rep->AmountCol(3, 4, -$assetsperiod, $dec);
+                               $rep->AmountCol(4, 5, -$assetsclose, $dec);
                                $rep->Font();
                                $rep->NewLine();
                        }
index 7101a73ab829fd20744bbfe434cabac6d56c840a..0e189c7981db8b988105fc94b04bc8b03b181e37 100644 (file)
@@ -48,7 +48,6 @@ function print_profit_and_loss_statement()
 {
        global $comp_path, $path_to_root;
 
-       include_once($path_to_root . "/reporting/includes/pdf_report.inc");
        $dim = get_company_pref('use_dimension');
        $dimension = $dimension2 = 0;
 
@@ -61,17 +60,30 @@ function print_profit_and_loss_statement()
                $dimension2 = $_POST['PARAM_4'];
                $graphics = $_POST['PARAM_5'];
                $comments = $_POST['PARAM_6'];
+               $destination = $_POST['PARAM_7'];
        }
        else if ($dim == 1)
        {
                $dimension = $_POST['PARAM_3'];
                $graphics = $_POST['PARAM_4'];
                $comments = $_POST['PARAM_5'];
+               $destination = $_POST['PARAM_6'];
        }
        else
        {
                $graphics = $_POST['PARAM_3'];
                $comments = $_POST['PARAM_4'];
+               $destination = $_POST['PARAM_5'];
+       }
+       if (isset($destination) && $destination)
+       {
+               include_once($path_to_root . "/reporting/includes/excel_report.inc");
+               $filename = "ProfitAndLoss.xml";
+       }       
+       else
+       {
+               include_once($path_to_root . "/reporting/includes/pdf_report.inc");
+               $filename = "ProfitAndLoss.pdf";
        }
        if ($graphics)
        {
@@ -129,7 +141,7 @@ function print_profit_and_loss_statement()
                $headers[3] = _('Period Y-1');
        }
 
-       $rep = new FrontReport(_('Profit and Loss Statement'), "ProfitAndLoss.pdf", user_pagesize());
+       $rep = new FrontReport(_('Profit and Loss Statement'), $filename, user_pagesize());
 
        $rep->Font();
        $rep->Info($params, $cols, $headers, $aligns);
@@ -169,12 +181,13 @@ function print_profit_and_loss_statement()
                {
                        if ($group != '')
                        {
-                               $rep->Line($rep->row + 6);
-                               $rep->row -= 6;
+                               $rep->row += 6;
+                               $rep->Line($rep->row);
+                               $rep->NewLine();
                                $rep->TextCol(0, 2,     _('Total') . " " . $group);
-                               $rep->TextCol(2, 3,     number_format2($totalper, $dec));
-                               $rep->TextCol(3, 4,     number_format2($totalacc, $dec));
-                               $rep->TextCol(4, 5,     number_format2(Achieve($totalper, $totalacc), $pdec));
+                               $rep->AmountCol(2, 3, $totalper, $dec);
+                               $rep->AmountCol(3, 4, $totalacc, $dec);
+                               $rep->AmountCol(4, 5, Achieve($totalper, $totalacc), $pdec);
                                if ($graphics)
                                {
                                        $pg->x[] = $group;
@@ -182,21 +195,22 @@ function print_profit_and_loss_statement()
                                        $pg->z[] = abs($totalacc);
                                }
                                $totalper = $totalacc = 0.0;
-                               $rep->row -= ($rep->lineHeight + 4);
+                               $rep->NewLine();
                                if ($closeclass)
                                {
-                                       $rep->Line($rep->row + 6);
-                                       $rep->row -= 6;
+                                       $rep->row += 6;
+                                       $rep->Line($rep->row);
+                                       $rep->NewLine();
                                        $rep->Font('bold');
                                        $rep->TextCol(0, 2,     _('Total') . " " . $classname);
-                                       $rep->TextCol(2, 3,     number_format2($classper, $dec));
-                                       $rep->TextCol(3, 4,     number_format2($classacc, $dec));
-                                       $rep->TextCol(4, 5,     number_format2(Achieve($classper, $classacc), $pdec));
+                                       $rep->AmountCol(2, 3, $classper, $dec);
+                                       $rep->AmountCol(3, 4, $classacc, $dec);
+                                       $rep->AmountCol(4, 5, Achieve($classper, $classacc), $pdec);
                                        $rep->Font();
                                        $salesper += $classper;
                                        $salesacc += $classacc;
                                        $classper = $classacc = 0.0;
-                                       $rep->NewLine(3);
+                                       $rep->NewLine(2);
                                        $closeclass = false;
                                }
                        }
@@ -205,12 +219,14 @@ function print_profit_and_loss_statement()
                                $rep->Font('bold');
                                $rep->TextCol(0, 5, $account['AccountClassName']);
                                $rep->Font();
-                               $rep->row -= ($rep->lineHeight + 4);
+                               $rep->NewLine();
                        }
                        $group = $account['AccountTypeName'];
+                       $rep->row -= 4;
                        $rep->TextCol(0, 5, $account['AccountTypeName']);
-                       $rep->Line($rep->row - 4);
-                       $rep->row -= ($rep->lineHeight + 4);
+                       $rep->row -= 4;
+                       $rep->Line($rep->row);
+                       $rep->NewLine();
                }
                $classname = $account['AccountClassName'];
 
@@ -223,9 +239,9 @@ function print_profit_and_loss_statement()
                $rep->TextCol(0, 1,     $account['account_code']);
                $rep->TextCol(1, 2,     $account['account_name']);
 
-               $rep->TextCol(2, 3,     number_format2($per_balance, $dec));
-               $rep->TextCol(3, 4,     number_format2($acc_balance, $dec));
-               $rep->TextCol(4, 5,     number_format2(Achieve($per_balance, $acc_balance), $pdec));
+               $rep->AmountCol(2, 3, $per_balance, $dec);
+               $rep->AmountCol(3, 4, $acc_balance, $dec);
+               $rep->AmountCol(4, 5, Achieve($per_balance, $acc_balance), $pdec);
 
                $rep->NewLine();
 
@@ -246,37 +262,40 @@ function print_profit_and_loss_statement()
        {
                if ($group != '')
                {
-                       $rep->Line($rep->row + 6);
-                       $rep->row -= 6;
+                       $rep->row += 6;
+                       $rep->Line($rep->row);
+                       $rep->NewLine();
                        $rep->TextCol(0, 2,     _('Total') . " " . $group);
-                       $rep->TextCol(2, 3,     number_format2($totalper, $dec));
-                       $rep->TextCol(3, 4,     number_format2($totalacc, $dec));
-                       $rep->TextCol(4, 5,     number_format2(Achieve($totalper, $totalacc), $pdec));
+                       $rep->AmountCol(2, 3, $totalper, $dec);
+                       $rep->AmountCol(3, 4, $totalacc, $dec);
+                       $rep->AmountCol(4, 5, Achieve($totalper, $totalacc), $pdec);
                        if ($graphics)
                        {
                                $pg->x[] = $group;
                                $pg->y[] = abs($totalper);
                                $pg->z[] = abs($totalacc);
                        }
-                       $rep->row -= ($rep->lineHeight + 4);
+                       $rep->NewLine();
                        if ($closeclass)
                        {
                                $rep->Line($rep->row + 6);
                                $calculateper = $salesper + $classper;
                                $calculateacc = $salesacc + $classacc;
-                               $rep->row -= 6;
+                               $rep->row += 6;
+                               $rep->Line($rep->row);
+                               $rep->NewLine();
 
                                $rep->Font('bold');
                                $rep->TextCol(0, 2,     _('Total') . " " . $classname);
-                               $rep->TextCol(2, 3,     number_format2($classper, $dec));
-                               $rep->TextCol(3, 4,     number_format2($classacc, $dec));
-                               $rep->TextCol(4, 5,     number_format2(Achieve($classper, $classacc), $pdec));
+                               $rep->AmountCol(2, 3, $classper, $dec);
+                               $rep->AmountCol(3, 4, $classacc, $dec);
+                               $rep->AmountCol(4, 5, Achieve($classper, $classacc), $pdec);
 
-                               $rep->row -= ($rep->lineHeight + 8);
+                               $rep->NewLine(2);
                                $rep->TextCol(0, 2,     _('Calculated Return'));
-                               $rep->TextCol(2, 3,     number_format2($calculateper, $dec));
-                               $rep->TextCol(3, 4,     number_format2($calculateacc, $dec));
-                               $rep->TextCol(4, 5,     number_format2(Achieve($calculateper, $calculateacc), $pdec));
+                               $rep->AmountCol(2, 3, $calculateper, $dec);
+                               $rep->AmountCol(3, 4, $calculateacc, $dec);
+                               $rep->AmountCol(4, 5, Achieve($calculateper, $calculateacc), $pdec);
                                if ($graphics)
                                {
                                        $pg->x[] = _('Calculated Return');
index a27d1d0f7d9c161f8e089482330c085f95379c85..e7c4b7bcbb93c90e1b1d7db71c9078bb8099b0e8 100644 (file)
@@ -31,37 +31,46 @@ $reports->addReport(_('Customer'),101,_('Customer &Balances'),
        array(  new ReportParam(_('End Date'),'DATE'),
                        new ReportParam(_('Customer'),'CUSTOMERS_NO_FILTER'),
                        new ReportParam(_('Currency Filter'),'CURRENCY'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('Customer'),102,_('&Aged Customer Analysis'),
        array(  new ReportParam(_('End Date'),'DATE'),
                        new ReportParam(_('Customer'),'CUSTOMERS_NO_FILTER'),
                        new ReportParam(_('Currency Filter'),'CURRENCY'),
                        new ReportParam(_('Summary Only'),'YES_NO'),
                        new ReportParam(_('Graphics'),'GRAPHIC'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('Customer'),103,_('Customer &Detail Listing'),
        array(  new ReportParam(_('Activity Since'),'DATEBEGIN'),
                        new ReportParam(_('Sales Areas'),'AREAS'),
-                       new ReportParam(_('Sales Folk'),'SALESMEN'), new ReportParam(_('Activity Greater Than'),'TEXT'), new ReportParam(_('Activity Less Than'),'TEXT'), new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Sales Folk'),'SALESMEN'), 
+                       new ReportParam(_('Activity Greater Than'),'TEXT'), 
+                       new ReportParam(_('Activity Less Than'),'TEXT'), 
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('Customer'),104,_('&Price Listing'),
        array(  new ReportParam(_('Currency Filter'),'CURRENCY'),
                        new ReportParam(_('Inventory Category'),'CATEGORIES'),
                        new ReportParam(_('Sales Types'),'SALESTYPES'),
                        new ReportParam(_('Show Pictures'),'YES_NO'),
                        new ReportParam(_('Show GP %'),'YES_NO'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('Customer'),105,_('&Order Status Listing'),
        array(  new ReportParam(_('Start Date'),'DATEBEGINM'),
                        new ReportParam(_('End Date'),'DATEENDM'),
                        new ReportParam(_('Inventory Category'),'CATEGORIES'),
                        new ReportParam(_('Stock Location'),'LOCATIONS'),
                        new ReportParam(_('Back Orders Only'),'YES_NO'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('Customer'),106,_('&Salesman Listing'),
        array(  new ReportParam(_('Start Date'),'DATEBEGINM'),
                        new ReportParam(_('End Date'),'DATEENDM'),
                        new ReportParam(_('Summary Only'),'YES_NO'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('Customer'),107,_('Print &Invoices/Credit Notes'),
        array(  new ReportParam(_('From'),'INVOICE'),
                        new ReportParam(_('To'),'INVOICE'),
@@ -95,22 +104,26 @@ $reports->addReport(_('Supplier'),201,_('Supplier &Balances'),
        array(  new ReportParam(_('End Date'),'DATE'),
                        new ReportParam(_('Supplier'),'SUPPLIERS_NO_FILTER'),
                        new ReportParam(_('Currency Filter'),'CURRENCY'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('Supplier'),202,_('&Aged Supplier Analyses'),
        array(  new ReportParam(_('End Date'),'DATE'),
                        new ReportParam(_('Supplier'),'SUPPLIERS_NO_FILTER'),
                        new ReportParam(_('Currency Filter'),'CURRENCY'),
                        new ReportParam(_('Summary Only'),'YES_NO'),
                        new ReportParam(_('Graphics'),'GRAPHIC'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('Supplier'),203,_('&Payment Report'),
        array(  new ReportParam(_('End Date'),'DATE'),
                        new ReportParam(_('Supplier'),'SUPPLIERS_NO_FILTER'),
                        new ReportParam(_('Currency Filter'),'CURRENCY'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('Supplier'),204,_('Outstanding &GRNs Report'),
        array(  new ReportParam(_('Supplier'),'SUPPLIERS_NO_FILTER'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('Supplier'),209,_('Print Purchase &Orders'),
        array(  new ReportParam(_('From'),'PO'),
                        new ReportParam(_('To'),'PO'),
@@ -124,30 +137,35 @@ $reports->addReport(_('Inventory'),301,_('Inventory &Valuation Report'),
        array(  new ReportParam(_('Inventory Category'),'CATEGORIES'),
                        new ReportParam(_('Location'),'LOCATIONS'),
                        new ReportParam(_('Detailed Report'),'YES_NO'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('Inventory'),302,_('Inventory &Planning Report'),
        array(  new ReportParam(_('Inventory Category'),'CATEGORIES'),
                        new ReportParam(_('Location'),'LOCATIONS'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('Inventory'),303,_('Stock &Check Sheets'),
        array(  new ReportParam(_('Inventory Category'),'CATEGORIES'),
                        new ReportParam(_('Location'),'LOCATIONS'),
                        new ReportParam(_('Show Pictures'),'YES_NO'),
                        new ReportParam(_('Inventory Column'),'YES_NO'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('Inventory'),304,_('Inventory &Sales Report'),
        array(  new ReportParam(_('Start Date'),'DATEBEGINM'),
                        new ReportParam(_('End Date'),'DATEENDM'),
                        new ReportParam(_('Inventory Category'),'CATEGORIES'),
                        new ReportParam(_('Location'),'LOCATIONS'),
                        new ReportParam(_('Detailed Report'),'YES_NO'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 
 $reports->addReportClass(_('Manufactoring'));
 $reports->addReport(_('Manufactoring'),401,_('&Bill of Material Listing'),
        array(  new ReportParam(_('From component'),'ITEMS'),
                        new ReportParam(_('To component'),'ITEMS'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        $reports->addReportClass(_('Dimensions'));
 if ($dim > 0)
 {
@@ -155,7 +173,8 @@ if ($dim > 0)
        array(  new ReportParam(_('From Dimension'),'DIMENSION'),
                        new ReportParam(_('To Dimension'),'DIMENSION'),
                        new ReportParam(_('Show Balance'),'YES_NO'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        //$reports->addReport(_('Dimensions'),502,_('Dimension Details'),
        //array(        new ReportParam(_('Dimension'),'DIMENSIONS'),
        //              new ReportParam(_('Comments'),'TEXTBOX')));
@@ -165,17 +184,20 @@ $reports->addReportClass(_('Banking'));
        array(  new ReportParam(_('Bank Accounts'),'BANK_ACCOUNTS'),
                        new ReportParam(_('Start Date'),'DATEBEGINM'),
                        new ReportParam(_('End Date'),'DATEENDM'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 
 $reports->addReportClass(_('General Ledger'));
 $reports->addReport(_('General Ledger'),701,_('Chart of &Accounts'),
        array(  new ReportParam(_('Show Balances'),'YES_NO'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 $reports->addReport(_('General Ledger'),702,_('List of &Journal Entries'),
        array(  new ReportParam(_('Start Date'),'DATEBEGINM'),
                        new ReportParam(_('End Date'),'DATEENDM'),
                        new ReportParam(_('Type'),'SYS_TYPES'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 //$reports->addReport(_('General Ledger'),703,_('GL Account Group Summary'),
 //     array(  new ReportParam(_('Comments'),'TEXTBOX')));
 if ($dim == 2)
@@ -187,19 +209,22 @@ if ($dim == 2)
                        new ReportParam(_('To Account'),'GL_ACCOUNTS'),
                        new ReportParam(_('Dimension')." 1", 'DIMENSIONS1'),
                        new ReportParam(_('Dimension')." 2", 'DIMENSIONS2'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        $reports->addReport(_('General Ledger'),705,_('Annual &Expense Breakdown'),
        array(  new ReportParam(_('Year'),'TRANS_YEARS'),
                        new ReportParam(_('Dimension')." 1", 'DIMENSIONS1'),
                        new ReportParam(_('Dimension')." 2", 'DIMENSIONS2'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        $reports->addReport(_('General Ledger'),706,_('&Balance Sheet'),
        array(  new ReportParam(_('Start Date'),'DATEBEGIN'),
                        new ReportParam(_('End Date'),'DATEENDM'),
                        new ReportParam(_('Dimension')." 1", 'DIMENSIONS1'),
                        new ReportParam(_('Dimension')." 2", 'DIMENSIONS2'),
                        new ReportParam(_('Graphics'),'GRAPHIC'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        $reports->addReport(_('General Ledger'),707,_('&Profit and Loss Statement'),
        array(  new ReportParam(_('Start Date'),'DATEBEGINM'),
                        new ReportParam(_('End Date'),'DATEENDM'),
@@ -207,7 +232,8 @@ if ($dim == 2)
                        new ReportParam(_('Dimension')." 1", 'DIMENSIONS1'),
                        new ReportParam(_('Dimension')." 2", 'DIMENSIONS2'),
                        new ReportParam(_('Graphics'),'GRAPHIC'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        $reports->addReport(_('General Ledger'),708,_('Trial &Balance'),
        array(  new ReportParam(_('Start Date'),'DATEBEGINM'),
                        new ReportParam(_('End Date'),'DATEENDM'),
@@ -215,7 +241,8 @@ if ($dim == 2)
                        new ReportParam(_('Only balances'),'YES_NO'),
                        new ReportParam(_('Dimension')." 1", 'DIMENSIONS1'),
                        new ReportParam(_('Dimension')." 2", 'DIMENSIONS2'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 }
 else if ($dim == 1)
 {
@@ -225,31 +252,36 @@ else if ($dim == 1)
                        new ReportParam(_('From Account'),'GL_ACCOUNTS'),
                        new ReportParam(_('To Account'),'GL_ACCOUNTS'),
                        new ReportParam(_('Dimension'), 'DIMENSIONS1'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        $reports->addReport(_('General Ledger'),705,_('Annual &Expense Breakdown'),
        array(  new ReportParam(_('Year'),'TRANS_YEARS'),
                        new ReportParam(_('Dimension'), 'DIMENSIONS1'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        $reports->addReport(_('General Ledger'),706,_('&Balance Sheet'),
        array(  new ReportParam(_('Start Date'),'DATEBEGIN'),
                        new ReportParam(_('End Date'),'DATEENDM'),
                        new ReportParam(_('Dimension'), 'DIMENSIONS1'),
                        new ReportParam(_('Graphics'),'GRAPHIC'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        $reports->addReport(_('General Ledger'),707,_('&Profit and Loss Statement'),
        array(  new ReportParam(_('Start Date'),'DATEBEGINM'),
                        new ReportParam(_('End Date'),'DATEENDM'),
                        new ReportParam(_('Compare to'),'COMPARE'),
                        new ReportParam(_('Dimension'), 'DIMENSIONS1'),
                        new ReportParam(_('Graphics'),'GRAPHIC'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        $reports->addReport(_('General Ledger'),708,_('Trial &Balance'),
        array(  new ReportParam(_('Start Date'),'DATEBEGINM'),
                        new ReportParam(_('End Date'),'DATEENDM'),
                        new ReportParam(_('Zero values'),'YES_NO'),
                        new ReportParam(_('Only balances'),'YES_NO'),
                        new ReportParam(_('Dimension'), 'DIMENSIONS1'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 }
 else
 {
@@ -258,33 +290,40 @@ else
                        new ReportParam(_('End Date'),'DATEENDM'),
                        new ReportParam(_('From Account'),'GL_ACCOUNTS'),
                        new ReportParam(_('To Account'),'GL_ACCOUNTS'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        $reports->addReport(_('General Ledger'),705,_('Annual &Expense Breakdown'),
        array(  new ReportParam(_('Year'),'TRANS_YEARS'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        $reports->addReport(_('General Ledger'),706,_('&Balance Sheet'),
        array(  new ReportParam(_('Start Date'),'DATEBEGIN'),
                        new ReportParam(_('End Date'),'DATEENDM'),
                        new ReportParam(_('Graphics'),'GRAPHIC'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        $reports->addReport(_('General Ledger'),707,_('&Profit and Loss Statement'),
        array(  new ReportParam(_('Start Date'),'DATEBEGINM'),
                        new ReportParam(_('End Date'),'DATEENDM'),
                        new ReportParam(_('Compare to'),'COMPARE'),
                        new ReportParam(_('Graphics'),'GRAPHIC'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
        $reports->addReport(_('General Ledger'),708,_('Trial &Balance'),
        array(  new ReportParam(_('Start Date'),'DATEBEGINM'),
                        new ReportParam(_('End Date'),'DATEENDM'),
                        new ReportParam(_('Zero values'),'YES_NO'),
                        new ReportParam(_('Only balances'),'YES_NO'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 }
 $reports->addReport(_('General Ledger'),709,_('Ta&x Report'),
        array(  new ReportParam(_('Start Date'),'DATEBEGINTAX'),
                        new ReportParam(_('End Date'),'DATEENDTAX'),
                        new ReportParam(_('Summary Only'),'YES_NO'),
-                       new ReportParam(_('Comments'),'TEXTBOX')));
+                       new ReportParam(_('Comments'),'TEXTBOX'),
+                       new ReportParam(_('Destination'),'DESTINATION')));
 
 echo "<script language='javascript'>
                function onWindowLoad() {