Initial Commit of AgileBill Open Source
This commit is contained in:
1060
modules/report/class.Level.php
Normal file
1060
modules/report/class.Level.php
Normal file
File diff suppressed because it is too large
Load Diff
681
modules/report/class.Report.php
Normal file
681
modules/report/class.Report.php
Normal file
@@ -0,0 +1,681 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AgileBill - Open Billing Software
|
||||
*
|
||||
* This body of work is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the Open AgileBill License
|
||||
* License as published at http://www.agileco.com/agilebill/license1-4.txt
|
||||
*
|
||||
* For questions, help, comments, discussion, etc., please join the
|
||||
* Agileco community forums at http://forum.agileco.com/
|
||||
*
|
||||
* @link http://www.agileco.com/
|
||||
* @copyright 2004-2008 Agileco, LLC.
|
||||
* @license http://www.agileco.com/agilebill/license1-4.txt
|
||||
* @author Tony Landis <tony@agileco.com> and Thralling Penguin, LLC <http://www.thrallingpenguin.com>
|
||||
* @package AgileBill
|
||||
* @version 1.4.93
|
||||
*/
|
||||
|
||||
class BASE_ReportFormatter {
|
||||
var $output_path;
|
||||
var $output;
|
||||
|
||||
function setOutputDirectory($d)
|
||||
{
|
||||
$this->output_path = $d;
|
||||
}
|
||||
|
||||
function getOutput()
|
||||
{
|
||||
return $this->output;
|
||||
}
|
||||
}
|
||||
|
||||
class HTML_ReportFormatter extends BASE_ReportFormatter {
|
||||
var $indent = 0;
|
||||
var $coldata;
|
||||
var $level;
|
||||
var $div_count;
|
||||
|
||||
function setLevel(&$level)
|
||||
{
|
||||
$this->level =& $level;
|
||||
}
|
||||
|
||||
function setIndent($amount)
|
||||
{
|
||||
if($amount == "") return;
|
||||
$this->indent = $amount;
|
||||
}
|
||||
|
||||
function addRow()
|
||||
{
|
||||
$this->coldata = array();
|
||||
echo " <tr>\n";
|
||||
}
|
||||
|
||||
function endRow()
|
||||
{
|
||||
/* output the coldata */
|
||||
#if($this->indent) {
|
||||
# echo " <td width=\"{$this->indent}\"> </td>\n";
|
||||
#}
|
||||
$w = 100 / count($this->coldata);
|
||||
foreach($this->coldata as $col) {
|
||||
$tag = "td";
|
||||
if (is_a($col[1],'ReportStyle')) {
|
||||
$s = "style=\"".$col[1]->doHTML()."\"";
|
||||
if($col[1]->is_heading) $tag = "th scope=\"col\"";
|
||||
} else {
|
||||
$s = "";
|
||||
}
|
||||
|
||||
echo " <{$tag} {$s} width=\"{$w}%\">\n";
|
||||
echo " {$col[0]}\n";
|
||||
echo " </{$tag}>\n";
|
||||
}
|
||||
echo " </tr>\n";
|
||||
}
|
||||
|
||||
function addColumn($col, $style = '')
|
||||
{
|
||||
/* take a column and a style */
|
||||
$this->coldata[] = array($col, $style);
|
||||
}
|
||||
|
||||
function addTable($style, $heading)
|
||||
{
|
||||
$i = $this->indent / 30; if($i<0) $i = 0;
|
||||
++$i;
|
||||
$this->div_count = 0;
|
||||
|
||||
if($style != 'report_heading') {
|
||||
echo '<div id="level_'.$i.'">';
|
||||
$this->div_count += 1;
|
||||
}
|
||||
if($this->indent == 0) {
|
||||
if($style != 'level') {
|
||||
echo '<div id="'.$style.'">';
|
||||
$this->div_count += 1;
|
||||
}
|
||||
}
|
||||
echo $heading;
|
||||
echo '<table width="100%" border="0" cellspacing="0">';
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function endTable()
|
||||
{
|
||||
$i = $this->indent / 30; if($i<0) $i = 0;
|
||||
++$i;
|
||||
echo "</table>\n";
|
||||
|
||||
if($this->div_count == 1)
|
||||
echo "</div>\n";
|
||||
if($this->indent == 0) {
|
||||
if($this->div_count == 2)
|
||||
echo "</div>\n";
|
||||
}
|
||||
}
|
||||
|
||||
function startDocument($title = '')
|
||||
{
|
||||
ob_start();
|
||||
echo "<html>\n";
|
||||
echo "<head>\n";
|
||||
echo "<title>{$title}</title>\n";
|
||||
echo "<link rel=\"stylesheet\" href=\"".URL."themes/default_admin/report_style.css\" type=\"text/css\">";
|
||||
echo "</head>\n<body>\n";
|
||||
}
|
||||
|
||||
function endDocument()
|
||||
{
|
||||
echo "</body>\n</html>\n";
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->output = $this->output_path."/report.html";
|
||||
$fp = fopen($this->output,'w');
|
||||
if($fp) {
|
||||
fwrite($fp,$content);
|
||||
fclose($fp);
|
||||
} else {
|
||||
echo 'Could not write to output file.';
|
||||
}
|
||||
}
|
||||
|
||||
function addBreak()
|
||||
{
|
||||
echo "<br /><br /><br />";
|
||||
}
|
||||
|
||||
function insertImage($file,$width,$height)
|
||||
{
|
||||
$file = basename($file);
|
||||
echo "<center><img src=\"$file\" width=\"$width\" height=\"$height\" /></center>\n";
|
||||
}
|
||||
|
||||
function write($s)
|
||||
{
|
||||
echo $s;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the report in DOS text format
|
||||
*/
|
||||
class TXT_ReportFormatter extends BASE_ReportFormatter {
|
||||
var $indent = 0;
|
||||
var $aindent;
|
||||
var $coldata;
|
||||
var $level;
|
||||
|
||||
function setLevel(&$level)
|
||||
{
|
||||
$this->level =& $level;
|
||||
}
|
||||
|
||||
function setIndent($amount)
|
||||
{
|
||||
if($amount == "") return;
|
||||
$this->indent = $amount;
|
||||
}
|
||||
|
||||
function addRow()
|
||||
{
|
||||
$this->coldata = array();
|
||||
}
|
||||
|
||||
function endRow()
|
||||
{
|
||||
/* output the coldata */
|
||||
if($this->indent) {
|
||||
$n = intval($this->indent) / 30;
|
||||
echo str_repeat(" ", $n);
|
||||
}
|
||||
$w = (100 / count($this->coldata))/100 * 80;
|
||||
foreach($this->coldata as $col) {
|
||||
echo str_pad($col[0], $w);
|
||||
}
|
||||
echo "\r\n";
|
||||
}
|
||||
|
||||
function addColumn($col, $style = '')
|
||||
{
|
||||
/* take a column and a style */
|
||||
$this->coldata[] = array($col, $style);
|
||||
}
|
||||
|
||||
function addTable($style, $heading=false)
|
||||
{
|
||||
if($this->indent) {
|
||||
echo "\r\n";
|
||||
$this->aindent = $this->indent;
|
||||
} else {
|
||||
echo "\r\n\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
function endTable()
|
||||
{
|
||||
if($this->indent && $this->indent != $this->aindent) echo "\r\n";
|
||||
}
|
||||
|
||||
function startDocument($title = '')
|
||||
{
|
||||
ob_start();
|
||||
}
|
||||
|
||||
function endDocument()
|
||||
{
|
||||
$content = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->output = $this->output_path."/report.txt";
|
||||
$fp = fopen($this->output,'w');
|
||||
if($fp) {
|
||||
fwrite($fp,$content);
|
||||
fclose($fp);
|
||||
} else {
|
||||
echo 'Could not write to output file.';
|
||||
}
|
||||
}
|
||||
|
||||
function addBreak()
|
||||
{
|
||||
echo "\r\n\r\n";
|
||||
}
|
||||
|
||||
function insertImage($file,$width,$height)
|
||||
{
|
||||
$file = basename($file);
|
||||
echo "\r\nSee file: $file\r\n";
|
||||
}
|
||||
|
||||
function write($s)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class PDF_ReportFormatter extends BASE_ReportFormatter {
|
||||
var $indent = 0;
|
||||
var $aindent;
|
||||
var $coldata;
|
||||
var $pdf;
|
||||
var $y;
|
||||
var $level;
|
||||
|
||||
function write($s)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function setIndent($amount)
|
||||
{
|
||||
if($amount == "") return;
|
||||
$this->indent = intval($amount);
|
||||
}
|
||||
|
||||
function addRow()
|
||||
{
|
||||
$this->coldata = array();
|
||||
}
|
||||
|
||||
function endRow()
|
||||
{
|
||||
$x = 9;
|
||||
$n = 0;
|
||||
/* output the coldata */
|
||||
if($this->indent) {
|
||||
$n = $this->indent / 30;
|
||||
$x += ($n * 9);
|
||||
}
|
||||
$w = round((100 / count($this->coldata))/100 * (190 - ($n*9)));
|
||||
$tx = $x;
|
||||
foreach($this->coldata as $col) {
|
||||
if (is_a($col[1],'ReportStyle')) {
|
||||
/* set the bounding area */
|
||||
$col[1]->setBounds($tx,$this->y,$tx + $w,$this->y + 5);
|
||||
$col[1]->doPDF($this->pdf);
|
||||
} else {
|
||||
$tmp = new ReportStyle;
|
||||
$tmp->doPDF($this->pdf);
|
||||
}
|
||||
#echo "x={$tx} y={$this->y} data={$col[0]} style={$col[1]}<br>";
|
||||
$this->pdf->Text($tx, $this->y,$col[0]);
|
||||
$tx += $w;
|
||||
}
|
||||
$this->addY(5, true);
|
||||
}
|
||||
|
||||
function addY($y, $repeatLabels = false)
|
||||
{
|
||||
$this->y += $y;
|
||||
if ($this->y > 275) {
|
||||
$this->pdf->AddPage();
|
||||
$this->y = 5;
|
||||
if($repeatLabels)
|
||||
$this->level->addHeaderLabels();
|
||||
}
|
||||
}
|
||||
|
||||
function setLevel(&$level)
|
||||
{
|
||||
$this->level =& $level;
|
||||
}
|
||||
|
||||
function addColumn($col, $style = '')
|
||||
{
|
||||
/* take a column and a style */
|
||||
$this->coldata[] = array($col, $style);
|
||||
}
|
||||
|
||||
function addTable($style, $heading='')
|
||||
{
|
||||
if($this->indent) {
|
||||
$this->addY(5);
|
||||
$this->aindent = $this->indent;
|
||||
} else {
|
||||
$this->addY(10);
|
||||
}
|
||||
|
||||
# if we're close to the end, goto next page
|
||||
if($this->y > 250) $this->addY(1000);
|
||||
}
|
||||
|
||||
function endTable()
|
||||
{
|
||||
if($this->indent && $this->indent != $this->aindent) $this->addY(5);
|
||||
}
|
||||
|
||||
function startDocument($title = '')
|
||||
{
|
||||
require_once(PATH_INCLUDES.'pdf/fpdi.php');
|
||||
require_once(PATH_INCLUDES.'pdf/fpdf_tpl.php');
|
||||
require_once(PATH_INCLUDES.'pdf/fpdf.php');
|
||||
|
||||
$this->pdf = new fpdi;
|
||||
$this->pdf->addPage();
|
||||
$this->y = 5;
|
||||
}
|
||||
|
||||
function endDocument()
|
||||
{
|
||||
$file = $this->output_path."/report.pdf";
|
||||
$this->output = $file;
|
||||
$this->pdf->Output($file,'F');
|
||||
}
|
||||
|
||||
function addBreak()
|
||||
{
|
||||
$this->addY(10);
|
||||
}
|
||||
|
||||
function insertImage($file,$width,$height)
|
||||
{
|
||||
$w = $width / 11.81102 * 2.5;
|
||||
$h = $height / 11.81102 * 2.5;
|
||||
$y = $this->y + 5;
|
||||
$x = 105 - ($w/2);
|
||||
#echo 'Place image at 0,'.$y." $w x $h<br>";
|
||||
$this->pdf->Image($file, $x, $y, $w, $h);
|
||||
$this->y = $y + $h + 5;
|
||||
}
|
||||
}
|
||||
|
||||
class ReportStyle {
|
||||
var $font_weight;
|
||||
var $font_family;
|
||||
var $font_height;
|
||||
var $bg_color;
|
||||
var $is_heading;
|
||||
var $tx, $ty, $bx, $by;
|
||||
|
||||
function ReportStyle()
|
||||
{
|
||||
$this->font_weight = '';
|
||||
$this->font_family = 'times';
|
||||
$this->font_height = 10;
|
||||
$this->is_heading = false;
|
||||
}
|
||||
|
||||
function fontFamily($f)
|
||||
{
|
||||
$this->font_family = $f;
|
||||
}
|
||||
|
||||
function fontHeight($h)
|
||||
{
|
||||
$this->font_height = $h;
|
||||
}
|
||||
|
||||
function bold()
|
||||
{
|
||||
$this->font_weight = 'bold';
|
||||
}
|
||||
|
||||
function backgroundColor($r,$g,$b)
|
||||
{
|
||||
$this->bg_color = array($r,$g,$b);
|
||||
}
|
||||
|
||||
function setBounds($x1,$y1,$x2,$y2)
|
||||
{
|
||||
$this->tx = $x1; $this->ty = $y1;
|
||||
$this->bx = $x2; $this->by = $y2;
|
||||
#echo "BOUNDS: $x1 x $y1 x $x2 x $y2<br>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the PDF style
|
||||
*/
|
||||
function doPDF(&$pdf)
|
||||
{
|
||||
if(is_array($this->bg_color)) {
|
||||
$x1 = $this->tx;
|
||||
$y1 = $this->ty - ($this->font_height * 0.352777778);
|
||||
$w = $this->bx - $this->tx;
|
||||
$h = $this->by - $this->ty;
|
||||
$pdf->SetFillColor($this->bg_color[0],$this->bg_color[1],$this->bg_color[2]);
|
||||
$pdf->Rect($x1,$y1,$w,$h,'F');
|
||||
#echo "BOX: $x1 x $y1 x $w x $h<br>";
|
||||
}
|
||||
|
||||
$b = ($this->font_weight == 'bold' ? "B" : "");
|
||||
|
||||
$pdf->SetFont($this->font_family,$b,$this->font_height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the HTML style
|
||||
*/
|
||||
function doHTML()
|
||||
{
|
||||
$s = "font-family: {$this->font_family}; font-size: {$this->font_height}pt;";
|
||||
if($this->font_weight == 'bold')
|
||||
$s .= " font-weight: bold;";
|
||||
if(is_array($this->bg_color)) {
|
||||
$s .= " background-color: #";
|
||||
$s .= str_pad(dechex($this->bg_color[0]), 2, '0', STR_PAD_LEFT);
|
||||
$s .= str_pad(dechex($this->bg_color[1]), 2, '0', STR_PAD_LEFT);
|
||||
$s .= str_pad(dechex($this->bg_color[2]), 2, '0', STR_PAD_LEFT);
|
||||
$s .= ";";
|
||||
}
|
||||
$s="";
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is a adaptor pattern that serves to place a break in the formatting of the report.
|
||||
*/
|
||||
class Report_BreakAdaptor {
|
||||
function display($grouping, $aggregate, &$formatter)
|
||||
{
|
||||
$formatter->addBreak();
|
||||
}
|
||||
}
|
||||
|
||||
require_once PATH_MODULES.'report/class.Level.php';
|
||||
class Report_DivAdaptor extends Level_Base {
|
||||
var $id;
|
||||
var $lev_setting;
|
||||
var $lev_fields;
|
||||
var $lev_items;
|
||||
var $indent_html;
|
||||
var $SQL_filtered;
|
||||
var $group_level;
|
||||
var $grouping_criteria;
|
||||
var $has_title;
|
||||
var $formatter;
|
||||
|
||||
function display($grouping, $aggregate, &$formatter)
|
||||
{
|
||||
$this->formatter =& $formatter;
|
||||
#echo "<div id=\"{$this->id}\">";
|
||||
if(isset($this->lev_items) && is_array($this->lev_items)) {
|
||||
foreach ($this->lev_items as $item) {
|
||||
echo "<div id=\"{$this->id}\">";
|
||||
$c = $this->formatter->indent;
|
||||
$item->display($grouping, $aggregate, $this->formatter);
|
||||
$this->formatter->indent = $c;
|
||||
echo "</div>";
|
||||
}
|
||||
}
|
||||
#echo "</div>";
|
||||
}
|
||||
}
|
||||
|
||||
class Reporting {
|
||||
var $has_header;
|
||||
var $rep_title;
|
||||
var $rep_subtitle_1;
|
||||
var $rep_subtitle_2;
|
||||
var $rep_date_start;
|
||||
var $rep_date_end;
|
||||
var $rep_image_src;
|
||||
var $rep_image_width;
|
||||
var $rep_image_height;
|
||||
var $rep_image_alt;
|
||||
var $rep_desc;
|
||||
var $rep_items;
|
||||
var $rep_formatter;
|
||||
|
||||
function Reporting (&$formatter, $has_header = false)
|
||||
{
|
||||
$this->has_header = $has_header;
|
||||
/*
|
||||
|
||||
TODO: Implement this crap at a later point
|
||||
|
||||
|
||||
$this->rep_title = $rep_title;
|
||||
$this->rep_subtitle_1 = $rep_subtitle_1;
|
||||
$this->rep_subtitle_2 = $rep_subtitle_2;
|
||||
$this->rep_date_start = $rep_date_start;
|
||||
$this->rep_date_end = $rep_date_end;
|
||||
$this->rep_desc = $rep_desc;
|
||||
$this->rep_image_src = $rep_image_src;
|
||||
$this->rep_image_width = $rep_image_width;
|
||||
$this->rep_image_height = $rep_image_height;
|
||||
$this->rep_image_alt = $rep_image_alt;
|
||||
*/
|
||||
$this->rep_formatter =& $formatter;
|
||||
}
|
||||
|
||||
function setTitle($t, $style = '')
|
||||
{
|
||||
if($style=='') $style = new ReportStyle;
|
||||
$style->fontHeight(16);
|
||||
$style->fontFamily('arial');
|
||||
$this->rep_title = array($t,$style);
|
||||
}
|
||||
|
||||
function setSubtitle1($t, $style = '')
|
||||
{
|
||||
if($style=='') $style = new ReportStyle;
|
||||
$style->fontHeight(14);
|
||||
$style->fontFamily('arial');
|
||||
$this->rep_subtitle_1 = array($t,$style);
|
||||
}
|
||||
|
||||
function setSubtitle2($t, $style = '')
|
||||
{
|
||||
if($style=='') $style = new ReportStyle;
|
||||
$style->fontHeight(12);
|
||||
$style->fontFamily('arial');
|
||||
$this->rep_subtitle_2 = array($t,$style);
|
||||
}
|
||||
|
||||
function addBreak ()
|
||||
{
|
||||
$this->rep_items[] = new Report_BreakAdaptor;
|
||||
}
|
||||
|
||||
function addDiv($id)
|
||||
{
|
||||
$item = new Report_DivAdaptor;
|
||||
$item->id = $id;
|
||||
$this->rep_items[] = $item;
|
||||
}
|
||||
|
||||
function append (&$item)
|
||||
{
|
||||
$this->rep_items[] =& $item;
|
||||
}
|
||||
|
||||
function display ()
|
||||
{
|
||||
$this->rep_formatter->startDocument($this->rep_title[0]);
|
||||
|
||||
if ($this->has_header) {
|
||||
$this->displayHeader();
|
||||
}
|
||||
if(is_array($this->rep_items)) {
|
||||
foreach ($this->rep_items as $item) {
|
||||
$cur = $this->rep_formatter->indent;
|
||||
$item->display(Null, Null, $this->rep_formatter);
|
||||
$this->rep_formatter->indent = $cur;
|
||||
}
|
||||
}
|
||||
$this->rep_formatter->endDocument();
|
||||
}
|
||||
|
||||
function displayHeader ()
|
||||
{
|
||||
if(is_a($this->rep_formatter,'HTML_ReportFormatter')) {
|
||||
if ($this->rep_title != '') {
|
||||
echo '<h1>'.$this->rep_title[0].'</h1>';
|
||||
}
|
||||
|
||||
if ($this->rep_subtitle_1 != '') {
|
||||
echo '<h2>'.$this->rep_subtitle_1[0].'</h2>';
|
||||
}
|
||||
|
||||
if ($this->rep_subtitle_2 != '') {
|
||||
echo '<h3>'.$this->rep_subtitle_2[0].'</h3>';
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->rep_formatter->addTable('report_heading');
|
||||
|
||||
if ($this->rep_image_src != '') {
|
||||
|
||||
echo "<td class='rc-rep-image-cell'>";
|
||||
|
||||
$width_html = '';
|
||||
$height_html = '';
|
||||
$alt_html = '';
|
||||
|
||||
if ($this->rep_image_width != '') {
|
||||
$width_html = " width='$this->rep_image_width'";
|
||||
}
|
||||
|
||||
echo "<td class='rc-rep-image-cell'$width_html>";
|
||||
|
||||
if ($this->rep_image_height != '') {
|
||||
$height_html = " height='$this->rep_image_height'";
|
||||
}
|
||||
|
||||
if ($this->rep_image_alt != '') {
|
||||
$alt_html = " alt='$this->rep_image_alt'";
|
||||
}
|
||||
|
||||
echo "<img class='rc-rep-image' src='$this->rep_image_src' $width_html $height_html $alt_html >
|
||||
</td>";
|
||||
}
|
||||
|
||||
$d = "";
|
||||
if ($this->rep_title != '') {
|
||||
$this->rep_formatter->addRow();
|
||||
$this->rep_formatter->addColumn($this->rep_title[0],$this->rep_title[1]);
|
||||
$this->rep_formatter->endRow();
|
||||
}
|
||||
|
||||
if ($this->rep_subtitle_1 != '') {
|
||||
$this->rep_formatter->addRow();
|
||||
$this->rep_formatter->addColumn($this->rep_subtitle_1[0],$this->rep_subtitle_1[1]);
|
||||
$this->rep_formatter->endRow();
|
||||
}
|
||||
|
||||
if ($this->rep_subtitle_2 != '') {
|
||||
$this->rep_formatter->addRow();
|
||||
$this->rep_formatter->addColumn($this->rep_subtitle_2[0],$this->rep_subtitle_2[1]);
|
||||
$this->rep_formatter->endRow();
|
||||
}
|
||||
|
||||
# $d .= "<h3>Report generated on " . date("d/m/y") . "</h3>";
|
||||
|
||||
if ($this->rep_desc != '') {
|
||||
$d .= "<h3>$this->rep_desc</h3>";
|
||||
}
|
||||
|
||||
$this->rep_formatter->addRow();
|
||||
$this->rep_formatter->addColumn(' ');
|
||||
$this->rep_formatter->endRow();
|
||||
$this->rep_formatter->endTable();
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
420
modules/report/class.ReportParser.php
Normal file
420
modules/report/class.ReportParser.php
Normal file
@@ -0,0 +1,420 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AgileBill - Open Billing Software
|
||||
*
|
||||
* This body of work is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the Open AgileBill License
|
||||
* License as published at http://www.agileco.com/agilebill/license1-4.txt
|
||||
*
|
||||
* For questions, help, comments, discussion, etc., please join the
|
||||
* Agileco community forums at http://forum.agileco.com/
|
||||
*
|
||||
* @link http://www.agileco.com/
|
||||
* @copyright 2004-2008 Agileco, LLC.
|
||||
* @license http://www.agileco.com/agilebill/license1-4.txt
|
||||
* @author Tony Landis <tony@agileco.com> and Thralling Penguin, LLC <http://www.thrallingpenguin.com>
|
||||
* @package AgileBill
|
||||
* @version 1.4.93
|
||||
*/
|
||||
|
||||
set_include_path(PATH_SEPARATOR.PATH_INCLUDES."pear");
|
||||
require_once 'XML/Parser.php';
|
||||
|
||||
class reportColumnTag
|
||||
{
|
||||
var $type;
|
||||
var $sql = '';
|
||||
var $criteria = '';
|
||||
var $orderby = '';
|
||||
var $indent = 0;
|
||||
var $display = '';
|
||||
var $field = '';
|
||||
var $aggregate = false;
|
||||
var $width = '';
|
||||
var $format = '';
|
||||
var $group_children_by = false;
|
||||
var $visible = true;
|
||||
var $hide_dups = false;
|
||||
var $condition = '';
|
||||
var $sql_criteria = '';
|
||||
var $total = false;
|
||||
var $total_format = '';
|
||||
var $link = '';
|
||||
var $user_criteria_table = '';
|
||||
var $user_criteria_col_id = '';
|
||||
var $user_criteria_col_name = '';
|
||||
var $user_criteria_date_format = 'Y-m';
|
||||
var $user_criteria_type;
|
||||
var $user_criteria;
|
||||
var $user_criteria_aggregate;
|
||||
|
||||
function reportColumnTag()
|
||||
{
|
||||
$this->type = 'reportLevelTag';
|
||||
$this->user_criteria = false;
|
||||
}
|
||||
}
|
||||
|
||||
class reportDatasetTag
|
||||
{
|
||||
var $type;
|
||||
var $sql = '';
|
||||
var $criteria = '';
|
||||
var $orderby = '';
|
||||
|
||||
function reportDatasetTag()
|
||||
{
|
||||
$this->type = 'reportDatasetTag';
|
||||
}
|
||||
}
|
||||
|
||||
class ReportParser extends XML_Parser
|
||||
{
|
||||
// Holds a reference to the reporting root class
|
||||
var $reportClass;
|
||||
// Holds the cdata as we parse a given tag
|
||||
var $cdata;
|
||||
// Holds our processing objects in a first in - last out (FILO) manner
|
||||
var $stack;
|
||||
|
||||
// Holds the fields the user may edit and change
|
||||
var $user_criteria;
|
||||
// Holds the fields the user has changed
|
||||
var $user_criteria_data;
|
||||
// Holds the fields that have been added
|
||||
var $user_criteria_fields;
|
||||
|
||||
function ReportParser(&$reportClass)
|
||||
{
|
||||
static $uc;
|
||||
static $ucd;
|
||||
static $ucf;
|
||||
|
||||
$this->user_criteria =& $uc;
|
||||
$this->user_criteria_data =& $ucd;
|
||||
$this->user_criteria_fields =& $ucf;
|
||||
|
||||
# Create the user criteria fields as static members
|
||||
|
||||
if(!is_a($reportClass,'Reporting')) die('Parameter 1 must be a Reporting reference.');
|
||||
# Save the Reporting reference
|
||||
$this->reportClass =& $reportClass;
|
||||
# Clear the cdata buffer
|
||||
$this->cdata = "";
|
||||
# Init the stack
|
||||
$this->stack = array();
|
||||
# Call into XML_Parser, to set us up the bomb. (See references on ALL YOUR BASE R BELONG TO US - Seriously, it's funny shit.)
|
||||
parent::XML_Parser();
|
||||
# Do NOT perform case foldering!
|
||||
$this->folding = false;
|
||||
}
|
||||
|
||||
function getUserCriteria()
|
||||
{
|
||||
return $this->user_criteria;
|
||||
}
|
||||
|
||||
function setUserCriteria($field, $condition, $value)
|
||||
{
|
||||
#$this->user_criteria_fields[] = $field;
|
||||
$this->user_criteria_data[] = array($field, $condition, $value);
|
||||
}
|
||||
|
||||
function getUserCriteriaSQL($field,&$isAggregate)
|
||||
{
|
||||
$sql = "";
|
||||
if(!is_array($this->user_criteria_data)) return '';
|
||||
foreach($this->user_criteria as $uc) {
|
||||
if($uc['name'] == $field) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach($this->user_criteria_data as $ucd) {
|
||||
if($ucd[0] == $field) {
|
||||
$db =& DB();
|
||||
|
||||
# format the field correctly
|
||||
switch($uc['type']) {
|
||||
case 'date':
|
||||
case 'date_year_month':
|
||||
$ucd[2] = date('Ym',$ucd[2]);
|
||||
break;
|
||||
case 'date_year':
|
||||
$ucd[2] = date('Y',$ucd[2]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(strpos(strtoupper($ucd[1]),'NULL') !== false) {
|
||||
$sql .= $field." ".$ucd[1];
|
||||
} else {
|
||||
if(ereg("^[0-9]+$",$ucd[2]))
|
||||
$sql .= $field." ".$ucd[1]." ".$ucd[2];
|
||||
else
|
||||
$sql .= $field." ".$ucd[1]." ".$db->qstr($ucd[2]);
|
||||
}
|
||||
$sql .= " AND ";
|
||||
}
|
||||
}
|
||||
if(strlen($sql))
|
||||
$sql = substr($sql,0,strlen($sql)-4);
|
||||
$isAggregate = $uc['aggregate'];
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function startHandler($xp, $name, $attr)
|
||||
{
|
||||
# Clear the cdata buffer
|
||||
$this->cdata = "";
|
||||
|
||||
if($name == 'report' && !count($this->stack)) {
|
||||
# initial outer report tag. set our start state.
|
||||
$this->stack[] =& $this->reportClass;
|
||||
return;
|
||||
} else if($name == 'level') {
|
||||
$this->stack[] = new Level;
|
||||
} else if($name == 'graph') {
|
||||
$this->stack[] = new LevelGraph(
|
||||
$attr['title'],
|
||||
intval($attr['width']),
|
||||
intval($attr['height']),
|
||||
$attr['type'],
|
||||
@$attr['direction'],
|
||||
@$attr['x_angle']
|
||||
);
|
||||
} else if($name == 'column') {
|
||||
$this->stack[] = new reportColumnTag;
|
||||
} else if($name == 'dataset') {
|
||||
$this->stack[] = new reportDatasetTag;
|
||||
} else if($name == 'break') {
|
||||
$work =& $this->last($this->stack);
|
||||
if($work) {
|
||||
$work->addBreak();
|
||||
}
|
||||
} else if($name == 'div') {
|
||||
$item = new Report_DivAdaptor;
|
||||
$item->id = $attr['id'];
|
||||
$this->stack[] =& $item;
|
||||
} else if($name == 'user_criteria') {
|
||||
$work =& $this->last($this->stack);
|
||||
if($work && is_a($work,'reportColumnTag')) {
|
||||
# validate the type
|
||||
switch($attr['type']) {
|
||||
case 'auto_affiliate':
|
||||
case 'auto_account':
|
||||
case 'menu':
|
||||
case 'bool':
|
||||
case 'text':
|
||||
case 'date_year_month':
|
||||
case 'date_year':
|
||||
case 'date':
|
||||
break;
|
||||
default:
|
||||
echo 'Error in user_criteria type.'; exit;
|
||||
}
|
||||
$work->user_criteria = true;
|
||||
$work->user_criteria_type = $attr['type'];
|
||||
$work->user_criteria_date_format = @$attr['date_format'];
|
||||
$work->user_criteria_table = @$attr['table'];
|
||||
$work->user_criteria_col_id = @$attr['col_id'];
|
||||
$work->user_criteria_col_name = @$attr['col_name'];
|
||||
$work->user_criteria_aggregate = @$attr['aggregate'];
|
||||
}
|
||||
}
|
||||
#echo '<pre>startHandler: '.$name."\n\n".print_r($this->stack,true).'</pre>';
|
||||
}
|
||||
|
||||
function endHandler($xp, $name)
|
||||
{
|
||||
if(strlen($this->cdata)) {
|
||||
while(preg_match("/%%([A-Z1-2_]+)%%/", $this->cdata, $regs)>0) {
|
||||
if(defined($regs[1])) {
|
||||
$this->cdata = str_replace("%%".$regs[1]."%%", constant($regs[1]), $this->cdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#echo "endHandler:$name<br>";
|
||||
$work =& $this->last($this->stack); array_pop($this->stack);
|
||||
#echo "Class Type: ".get_class($work)."<br>";
|
||||
#echo '<pre>endHandler: '.$name."\n\n".print_r($this->stack,true).'</pre>';
|
||||
if($name == 'report' && count($this->stack)==1) {
|
||||
#echo 'stack is empty. returning from endHandler.<br>';
|
||||
return;
|
||||
}
|
||||
|
||||
# Report
|
||||
if(is_a($work,'Reporting')) {
|
||||
if($name == 'title')
|
||||
$work->setTitle($this->cdata);
|
||||
else if($name == 'subtitle1')
|
||||
$work->setSubtitle1($this->cdata);
|
||||
else if($name == 'subtitle2')
|
||||
$work->setSubtitle2($this->cdata);
|
||||
}
|
||||
|
||||
# Level
|
||||
if(is_a($work,'Level')) {
|
||||
if($name == 'sql')
|
||||
$work->setSql($this->cdata);
|
||||
else if($name == 'criteria')
|
||||
$work->setCriteria($this->cdata);
|
||||
else if($name == 'orderby')
|
||||
$work->setOrderby($this->cdata);
|
||||
else if($name == 'indent')
|
||||
$work->setIndent($this->cdata);
|
||||
else if($name == 'title')
|
||||
$work->setTitle($this->cdata);
|
||||
else if($name == 'htmlstyle')
|
||||
$work->setClass($this->cdata);
|
||||
|
||||
else if($name == 'level') {
|
||||
$ltmp =& $work;
|
||||
$work =& $this->last($this->stack); array_pop($this->stack);
|
||||
# Do we have user criteria values on this?
|
||||
if(is_array($this->user_criteria_data)) {
|
||||
#echo '<pre>'.print_r($this->user_criteria_data,true).'</pre>';
|
||||
$tmp = $this->user_criteria_data;
|
||||
foreach($tmp as $f) {
|
||||
$a = false;
|
||||
$c = $this->getUserCriteriaSQL($f[0], $a);
|
||||
#echo "<pre>c=$c\n".print_r($f,true).'</pre>';
|
||||
if(strlen($c)) {
|
||||
$ltmp->addFieldCriteria($c, $a, $f[0]);
|
||||
}
|
||||
}
|
||||
#echo "<pre>".print_r($ltmp,true)."</pre>"; exit;
|
||||
}
|
||||
$work->append($ltmp);
|
||||
}
|
||||
}
|
||||
if(is_a($work,'Report_DivAdaptor')) {
|
||||
$ltmp =& $work;
|
||||
$work =& $this->last($this->stack); array_pop($this->stack);
|
||||
$work->append($ltmp);
|
||||
}
|
||||
if(is_a($work,'reportColumnTag')) {
|
||||
if($name == 'display')
|
||||
$work->display = $this->cdata;
|
||||
else if($name == 'field')
|
||||
$work->field = $this->cdata;
|
||||
else if($name == 'aggregate')
|
||||
$work->aggregate = $this->cdata == 'true' ? true : false;
|
||||
else if($name == 'width')
|
||||
$work->width = $this->cdata;
|
||||
else if($name == 'format')
|
||||
$work->format = $this->cdata;
|
||||
else if($name == 'group_children_by')
|
||||
$work->group_children_by = $this->cdata == 'true' ? true : false;
|
||||
else if($name == 'visible')
|
||||
$work->visible = $this->cdata == 'true' ? true : false;
|
||||
else if($name == 'hide_dups')
|
||||
$work->hide_dups = $this->cdata == 'true' ? true : false;
|
||||
else if($name == 'sql')
|
||||
$work->sql = $this->cdata;
|
||||
else if($name == 'sql_criteria')
|
||||
$work->sql_criteria = $this->cdata;
|
||||
else if($name == 'condition')
|
||||
$work->condition = $this->cdata;
|
||||
else if($name == 'total')
|
||||
$work->total = $this->cdata == 'true' ? true : false;
|
||||
else if($name == 'total_format')
|
||||
$work->total_format = $this->cdata;
|
||||
else if($name == 'link')
|
||||
$work->link = $this->cdata;
|
||||
else if($name == 'column') {
|
||||
$f =& $work;
|
||||
$work =& $this->last($this->stack); array_pop($this->stack);
|
||||
$work->addField($f->display, $f->field, $f->aggregate, $f->width,
|
||||
$f->format, $f->group_children_by, $f->visible, $f->hide_dups,
|
||||
'', false, '', false, $f->condition, '', $f->sql, $f->sql_criteria,
|
||||
0, '', '', false, $f->total, '', $f->total_format, '', false, $f->link
|
||||
);
|
||||
# If this field has user_criteria=true, then add it to the avail array
|
||||
if($f->user_criteria) {
|
||||
#echo "<pre>Trying\n".print_r($this->user_criteria_fields,true).'</pre>';
|
||||
|
||||
if(!is_array($this->user_criteria_fields) || !in_array(str_replace('.','',$f->field),$this->user_criteria_fields)) {
|
||||
$this->user_criteria[] = array(
|
||||
'name' => $f->field,
|
||||
'display' => $f->display,
|
||||
'type' => $f->user_criteria_type,
|
||||
'date_format' => $f->user_criteria_date_format,
|
||||
'values' => '',
|
||||
'table' => $f->user_criteria_table,
|
||||
'col_id' => $f->user_criteria_col_id,
|
||||
'col_name' => $f->user_criteria_col_name,
|
||||
'aggregate' => $f->aggregate
|
||||
);
|
||||
$this->user_criteria_fields[] = str_replace('.','',$f->field);
|
||||
#echo "<pre>LEVEL\n".print_r($this->user_criteria,true).'</pre>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(is_a($work,'LevelGraph')) {
|
||||
if($name == 'title')
|
||||
$work->setTitle($this->cdata);
|
||||
else if($name == 'graph') {
|
||||
# store the reference
|
||||
$ltmp =& $work;
|
||||
# pop the stack again
|
||||
$work =& $this->last($this->stack); array_pop($this->stack);
|
||||
|
||||
# Do we have user criteria values on this?
|
||||
if(is_array($this->user_criteria_data)) {
|
||||
$tmp = $this->user_criteria_data;
|
||||
foreach($tmp as $f) {
|
||||
$a = false;
|
||||
$c = $this->getUserCriteriaSQL($f[0], $a);
|
||||
#echo "<pre>c=$c\n".print_r($f,true).'</pre>';
|
||||
if(strlen($c)) {
|
||||
$ltmp->addFieldCriteria($c, $a, $f[0]);
|
||||
}
|
||||
}
|
||||
#echo "<pre>".print_r($ltmp,true)."</pre>"; exit;
|
||||
}
|
||||
# append this graph onto the level/report/graph below
|
||||
$work->append($ltmp);
|
||||
}
|
||||
}
|
||||
if(is_a($work,'reportDatasetTag')) {
|
||||
if($name == 'criteria')
|
||||
$work->criteria = $this->cdata;
|
||||
else if($name == 'orderby')
|
||||
$work->orderby = $this->cdata;
|
||||
else if($name == 'sql')
|
||||
$work->sql = $this->cdata;
|
||||
else if($name == 'dataset') {
|
||||
# store the reference
|
||||
$d =& $work;
|
||||
# pop the stack
|
||||
$work =& $this->last($this->stack); array_pop($this->stack);
|
||||
# add the dataset to the graph
|
||||
$work->addDataset($d->sql, $d->criteria, $d->orderby);
|
||||
}
|
||||
}
|
||||
# Push the worker object back onto the stack
|
||||
$this->stack[] =& $work;
|
||||
}
|
||||
|
||||
function cdataHandler($xp, $cdata)
|
||||
{
|
||||
$this->cdata .= $cdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the true class reference from an array, unlike any PHP function
|
||||
*/
|
||||
function &last(&$array) {
|
||||
if (!is_array($array))
|
||||
return null;
|
||||
if (!count($array))
|
||||
return false; // like end()
|
||||
return $array[count($array)-1];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
310
modules/report/report.inc.php
Normal file
310
modules/report/report.inc.php
Normal file
@@ -0,0 +1,310 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AgileBill - Open Billing Software
|
||||
*
|
||||
* This body of work is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the Open AgileBill License
|
||||
* License as published at http://www.agileco.com/agilebill/license1-4.txt
|
||||
*
|
||||
* For questions, help, comments, discussion, etc., please join the
|
||||
* Agileco community forums at http://forum.agileco.com/
|
||||
*
|
||||
* @link http://www.agileco.com/
|
||||
* @copyright 2004-2008 Agileco, LLC.
|
||||
* @license http://www.agileco.com/agilebill/license1-4.txt
|
||||
* @author Tony Landis <tony@agileco.com>
|
||||
* @package AgileBill
|
||||
* @version 1.4.93
|
||||
*/
|
||||
|
||||
/**
|
||||
* Agileco Report Module
|
||||
*/
|
||||
class report
|
||||
{
|
||||
/**
|
||||
* Get the list of available modules
|
||||
*/
|
||||
function module_menu($VAR)
|
||||
{
|
||||
global $C_translate;
|
||||
|
||||
if(!empty($VAR['report_module']))
|
||||
$default = $VAR['report_module'];
|
||||
else
|
||||
$default = false;
|
||||
|
||||
$return = '';
|
||||
|
||||
$path = PATH_AGILE . 'reports/';
|
||||
chdir($path);
|
||||
$dir = opendir($path);
|
||||
$count = 0;
|
||||
while ($file_name = readdir($dir))
|
||||
{
|
||||
if( $file_name != '..' && $file_name != '.' && !ereg(".xml", $file_name) && !ereg(".php", $file_name))
|
||||
{
|
||||
$name = $C_translate->translate('menu', $file_name, '');
|
||||
if(empty($name) && eregi("^[a-zA-Z0-9\-\_]{1,}", $file_name)) $name = strtoupper($file_name);
|
||||
if(!empty($name))
|
||||
{
|
||||
$return .= "<option value=\"{$file_name}\"";
|
||||
if($default == $file_name) $return .= " selected";
|
||||
$return .= ">{$name}</option>\n";
|
||||
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($count > 10) $count = 10;
|
||||
|
||||
echo '<select id="report_module" name="report_module" size="'.$count.'" onChange="submit()" multiple>';
|
||||
if($count==0)
|
||||
echo '<option value="">No Reports Available</option>';
|
||||
echo $return;
|
||||
echo '</select>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of available reports
|
||||
*/
|
||||
function report_menu($VAR)
|
||||
{
|
||||
global$C_translate;
|
||||
$C_xml = new CORE_xml;
|
||||
|
||||
if(empty($VAR['report_module'])) {
|
||||
echo $C_translate->translate('no_reports','report','');
|
||||
return;
|
||||
} else {
|
||||
$module = $VAR['report_module'];
|
||||
}
|
||||
|
||||
|
||||
if(!empty($VAR['report_template']))
|
||||
$default = $VAR['report_template'];
|
||||
else
|
||||
$default = false;
|
||||
|
||||
$return = '<select id="report_template" name="report_template" width="150" size="5" onChange="submit()" multiple>';
|
||||
|
||||
$path = PATH_AGILE . 'reports/'.$module.'/';
|
||||
chdir($path);
|
||||
$dir = opendir($path);
|
||||
$count = 0;
|
||||
while ($file_name = readdir($dir))
|
||||
{
|
||||
if($file_name != '..' && $file_name != '.' && ereg(".xml$", $file_name)) {
|
||||
$template = $C_xml->xml_to_array($path.$file_name);
|
||||
$name = $template['report']['title'];
|
||||
|
||||
|
||||
$return .= "<option value=\"{$file_name}\"";
|
||||
if($default == $file_name) $return .= " selected";
|
||||
$return .= ">{$name}</option>\n";
|
||||
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($count==0)
|
||||
$return .= '<option value="">'. $C_translate->translate('no_reports','report','').'</option>';
|
||||
$return .= '</select>';
|
||||
echo $return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get user criteria
|
||||
*/
|
||||
function get_user_criteria($VAR)
|
||||
{
|
||||
# validation
|
||||
if(empty($VAR['report_module']) || empty($VAR['report_template'])) return false;
|
||||
$module = $VAR['report_module'];
|
||||
$report = $VAR['report_template'];
|
||||
|
||||
# include reporting classess
|
||||
require_once PATH_MODULES . 'report/class.Report.php';
|
||||
require_once PATH_MODULES . 'report/class.Level.php';
|
||||
require_once PATH_MODULES . 'report/class.ReportParser.php';
|
||||
$f = new HTML_ReportFormatter;
|
||||
$r = new Reporting($f, true);
|
||||
$p = new ReportParser($r);
|
||||
$result = $p->setInputFile(PATH_AGILE.'reports/'.$module.'/'.$report);
|
||||
$result = $p->parse();
|
||||
|
||||
# pre-process the user criteria array
|
||||
$arr = $p->getUserCriteria();
|
||||
if(is_array($arr)) {
|
||||
foreach($arr as $cond) {
|
||||
if($cond['type']=='menu') {
|
||||
//print_r($cond);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
global $smarty;
|
||||
$smarty->assign('userCriteria', $arr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user criteria and display report
|
||||
*/
|
||||
function view($VAR)
|
||||
{
|
||||
# validation
|
||||
if(empty($VAR['report_module']) || empty($VAR['report_template'])) return false;
|
||||
$module = $VAR['report_module'];
|
||||
$report = $VAR['report_template'];
|
||||
$format = $VAR['report_format'];
|
||||
|
||||
# include reporting classess
|
||||
require_once PATH_MODULES . 'report/class.Report.php';
|
||||
require_once PATH_MODULES . 'report/class.Level.php';
|
||||
require_once PATH_MODULES . 'report/class.ReportParser.php';
|
||||
|
||||
set_time_limit(0);
|
||||
|
||||
if($format=='text')
|
||||
$f = new TXT_ReportFormatter;
|
||||
elseif($format=='html')
|
||||
$f = new HTML_ReportFormatter;
|
||||
elseif($format=='pdf')
|
||||
$f = new PDF_ReportFormatter;
|
||||
|
||||
# Tell the formatter where to save the output
|
||||
$dir = md5(tempnam(PATH_FILES, "s"));
|
||||
$path = PATH_FILES.'reports/'.$dir;
|
||||
@unlink($path);
|
||||
mkdir($path, 0775);
|
||||
$f->setOutputDirectory($path);
|
||||
|
||||
# set report construct file to use
|
||||
$r = new Reporting($f, true);
|
||||
$p = new ReportParser($r);
|
||||
$result = $p->setInputFile(PATH_AGILE.'reports/'.$module.'/'.$report);
|
||||
|
||||
# Get user criteria
|
||||
$arr = $p->getUserCriteria();
|
||||
|
||||
# Set the user criteria
|
||||
if(!empty($VAR['report']['conditions']) && is_array($VAR['report']['conditions'])) {
|
||||
foreach($VAR['report']['conditions'] as $arr) {
|
||||
$exp = $arr['exp'];
|
||||
$col = $arr['col'];
|
||||
$val = $arr['value'];
|
||||
$type= $arr['type'];
|
||||
foreach($col as $i=>$name) {
|
||||
if($type[$i] == 'date_year_month') {
|
||||
$val[$i] = array('month'=> $val['month'][$i], 'year'=> $val['year'][$i]);
|
||||
}
|
||||
$this->setSQLCondition($p, $col[$i], $exp[$i], $val[$i], $type[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#echo '<pre>'.print_r($p,true).'</pre>'; exit;
|
||||
$result = $p->parse();
|
||||
#echo '<pre>'.print_r($p,true).'</pre>'; exit;
|
||||
$r->display();
|
||||
|
||||
if($format=='text') {
|
||||
header('Content-type: text/txt');
|
||||
header('Content-Disposition: inline; filename="report.txt"');
|
||||
echo file_get_contents($f->getOutput());
|
||||
@unlink($f->getOutput());
|
||||
|
||||
} elseif($format=='html') {
|
||||
$f->getOutput();
|
||||
$url=URL.'includes/files/reports/'.$dir.'/report.html';
|
||||
echo "<script>document.location='$url';</script>";
|
||||
|
||||
} elseif ($format=='pdf') {
|
||||
header('Content-type: application/pdf');
|
||||
header('Content-Disposition: inline; filename="report.pdf"');
|
||||
readfile($f->getOutput());
|
||||
@unlink($f->getOutput());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get actual SQL contition from user input and add to userCondtions
|
||||
*/
|
||||
function setSQLCondition(&$reportObj, $column, $condition, $value=false, $type=false)
|
||||
{
|
||||
$o["EQ"] = '=';
|
||||
$o["NOT"] = '<>';
|
||||
|
||||
$o["GT"] = '>';
|
||||
$o["LT"] = '<';
|
||||
$o["GTEQ"] = '>=';
|
||||
$o["LTEQ"] = '<=';
|
||||
|
||||
$o["LIKE"] = 'LIKE';
|
||||
$o["NLIKE"] = 'IS NOT LIKE';
|
||||
|
||||
$o["NULL"] = 'IS NULL';
|
||||
$o["NNULL"] = 'IS NOT NULL';
|
||||
|
||||
// actual SQL condition
|
||||
$c = $o["$condition"];
|
||||
|
||||
// determine value
|
||||
if( $condition=="NULL" || $condition=="NNULL" )
|
||||
$v=false;
|
||||
elseif ($value=='')
|
||||
return false;
|
||||
else
|
||||
$v=$value;
|
||||
|
||||
if($type=='date') {
|
||||
$v=$this->convert_date_time($value);
|
||||
$reportObj->setUserCriteria($column, $c, $v);
|
||||
} elseif ($type=='date_year') {
|
||||
$v=mktime(0,0,0,1,1,$value);
|
||||
$reportObj->setUserCriteria($column, $c, $v);
|
||||
} elseif ($type=='date_year_month') {
|
||||
if(!empty($value['year'])) {
|
||||
if(empty($value['month'])) $month=1; else $month=$value['month'];
|
||||
$v=mktime(0,0,0,$month,1,$value['year']);
|
||||
$reportObj->setUserCriteria($column, $c, $v);
|
||||
}
|
||||
} else {
|
||||
$reportObj->setUserCriteria($column, $c, $v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* convert DEFAULT_DATE_TIME_FORMT to unix time stamp
|
||||
*/
|
||||
function convert_date_time ($date, $constraint=false)
|
||||
{
|
||||
if($date == '0' || $date == '')
|
||||
return '';
|
||||
|
||||
$Arr_format = split(DEFAULT_DATE_DIVIDER, UNIX_DATE_FORMAT);
|
||||
$Arr_date = split(DEFAULT_DATE_DIVIDER, $date);
|
||||
|
||||
for($i=0; $i<3; $i++)
|
||||
{
|
||||
if($Arr_format[$i] == 'd')
|
||||
$day = $Arr_date[$i];
|
||||
|
||||
if($Arr_format[$i] == 'm')
|
||||
$month = $Arr_date[$i];
|
||||
|
||||
if($Arr_format[$i] == 'Y')
|
||||
$year = $Arr_date[$i];
|
||||
}
|
||||
|
||||
$timestamp = mktime(23, 59, 59, $month, $day, $year);
|
||||
|
||||
return $timestamp;
|
||||
}
|
||||
}
|
||||
?>
|
63
modules/report/report_construct.xml
Normal file
63
modules/report/report_construct.xml
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<construct>
|
||||
<!-- define the module name -->
|
||||
<module>report</module>
|
||||
<!-- define the module table name -->
|
||||
<table>report</table>
|
||||
<!-- define the module dependancy(s) -->
|
||||
<dependancy/>
|
||||
<!-- define the DB cache in seconds -->
|
||||
<cache>0</cache>
|
||||
<!-- define the default order_by field for SQL queries -->
|
||||
<order_by>template,date_orig</order_by>
|
||||
<!-- define the methods -->
|
||||
<limit>35</limit>
|
||||
<!-- define indexes -->
|
||||
<index>
|
||||
<nickname>nickname</nickname>
|
||||
<template>template</template>
|
||||
</index>
|
||||
<!-- define the fields -->
|
||||
<field>
|
||||
<id>
|
||||
<type>I4</type>
|
||||
<unique>1</unique>
|
||||
</id>
|
||||
<site_id>
|
||||
<type>C(16)</type>
|
||||
</site_id>
|
||||
<date_orig>
|
||||
<type>I8</type>
|
||||
<convert>date-time</convert>
|
||||
</date_orig>
|
||||
<date_last>
|
||||
<type>I8</type>
|
||||
<convert>date-now</convert>
|
||||
</date_last>
|
||||
<template>
|
||||
<type>C(128)</type>
|
||||
</template>
|
||||
<nickname>
|
||||
<type>C(32)</type>
|
||||
<min_len>1</min_len>
|
||||
<max_len>32</max_len>
|
||||
</nickname>
|
||||
<criteria>
|
||||
<type>X2</type>
|
||||
<convert>array</convert>
|
||||
</criteria>
|
||||
<module>
|
||||
<type>C(32)</type>
|
||||
</module>
|
||||
</field>
|
||||
<!-- define all the methods for this class, and the fields they have access to, if applicable. -->
|
||||
<method>
|
||||
<add>id,site_id,date_orig,date_last,template,nickname,criteria,module</add>
|
||||
<update>id,site_id,date_orig,date_last,template,nickname,criteria,module</update>
|
||||
<delete>id,site_id,date_orig,date_last,template,nickname,criteria,module</delete>
|
||||
<view>id,site_id,date_orig,date_last,template,nickname,criteria,module</view>
|
||||
<search>id,site_id,date_orig,date_last,template,nickname,criteria,module</search>
|
||||
</method>
|
||||
<!-- define the method triggers -->
|
||||
<trigger>0</trigger>
|
||||
</construct>
|
27
modules/report/report_install.xml
Normal file
27
modules/report/report_install.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<install>
|
||||
|
||||
<!-- Define the main module properties -->
|
||||
<module_properties>
|
||||
<name>report</name>
|
||||
<parent>report</parent>
|
||||
<notes>Generate XML/XSL reports from the AgileBill database</notes>
|
||||
<menu_display>1</menu_display>
|
||||
<dependancy></dependancy>
|
||||
<sub_modules></sub_modules>
|
||||
</module_properties>
|
||||
|
||||
<!-- Define any SQL inserts for this module -->
|
||||
<sql_inserts>
|
||||
<module_method>
|
||||
<view>
|
||||
<name>view</name>
|
||||
<page>%%:main</page>
|
||||
<menu_display>1</menu_display>
|
||||
</view>
|
||||
<task_cleanup>
|
||||
<name>task_cleanup</name>
|
||||
</task_cleanup>
|
||||
</module_method>
|
||||
</sql_inserts>
|
||||
</install>
|
56
modules/report/test.php
Normal file
56
modules/report/test.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/*
|
||||
AgileReports
|
||||
(C) 2005-2006 Thralling Penguin LLC in association with Agileco LLC. All rights reserved.
|
||||
|
||||
*/
|
||||
|
||||
include "../../config.inc.php";
|
||||
include PATH_INCLUDES."adodb/adodb.inc.php";
|
||||
include PATH_MODULES."core/database.inc.php";
|
||||
|
||||
/*
|
||||
There are features still missing! But it's not a shabby start.
|
||||
*/
|
||||
|
||||
|
||||
# these three files make up the reporting system
|
||||
include 'class.Report.php';
|
||||
include 'class.Level.php';
|
||||
include 'class.ReportParser.php';
|
||||
|
||||
/* Good idea, reports can be a beast */
|
||||
set_time_limit(0);
|
||||
|
||||
/* Uncomment one of the output formater lines below */
|
||||
#$f = new TXT_ReportFormatter;
|
||||
$f = new HTML_ReportFormatter;
|
||||
#$f = new PDF_ReportFormatter;
|
||||
|
||||
# Tell the formatter where to save the output
|
||||
$dir = tempnam(PATH_FILES, "s");
|
||||
@unlink($dir);
|
||||
mkdir($dir, 0775);
|
||||
$f->setOutputDirectory($dir);
|
||||
|
||||
# This creates the report class, specifying the ReportFormatter to use and whether or not to paginate the title
|
||||
$r = new Reporting($f, true);
|
||||
# This creates the report XML parser, specify the report class object to use in building the report
|
||||
$p = new ReportParser($r);
|
||||
# This sets the XML report definition file
|
||||
#$result = $p->setInputFile(PATH_MODULES.'report/year_month_sales_by_sku.xml');
|
||||
$result = $p->setInputFile(PATH_AGILE.'reports/invoice/sales_report.xml');
|
||||
# set criteria
|
||||
$p->setUserCriteria('yearmonth','>=',mktime(0,0,0,1,1,2005));
|
||||
# Parse that puppy!
|
||||
$result = $p->parse();
|
||||
|
||||
/* COULD INSERT CODE TO DO SMARTY JUNK HERE - then skip the display call */
|
||||
/* COULD ALSO call back into $p to assign some SQL statement criteria changes from the UI/Smarty's POST/GET */
|
||||
|
||||
# Render my report, now!
|
||||
$r->display();
|
||||
|
||||
echo $f->getOutput();
|
||||
|
||||
?>
|
Reference in New Issue
Block a user