getElementValue($b); if(empty($b)) { $b=0; } //echo "$a,$b"; return $a ^ $b; } function newPDFPage(&$pdf,&$style,&$top,&$row_num,&$page_num,&$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT = false) { //cleanup $page_num++; $ext_page_num++; //reset row counter $row_num = 0; //reset height $top=HEIGHT-(FONTSIZE+LINESPACE); // Add a new page $pdf->pages[] = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4); // Assign the style $page =& $pdf->pages[$page_num-1]; $page->setStyle($style); //print out the header DrawHeader($hdrdata,$page,$top,$font,$boldfont); // Print SubHeading if($subtitle) { $top=$top-FONTSIZE-LINESPACE; DrawColumn($subcols, $subdata,$page,$top,$font,$boldfont, True); } // Print line between column heading and data $top=$top-LINESPACE-LINESPACE; $page->drawLine(0, $top, WIDTH, $top); // Print the column headings $top=$top-(FONTSIZE+LINESPACE); DrawColumn($cols, $coldata,$page,$top,$font,$boldfont, True); $top=$top-LINESPACE-LINESPACE; $page->drawLine(0, $top, WIDTH, $top); $top=$top-(FONTSIZE+LINESPACE); // Footer DrawFooter($ext_page_num,$page,$VAT); return $page; } function displayTotals($total_cost,$total_duration,$total_calls,&$page,&$top,$totalcols,$font,$boldfont,$VAT,$grand_total=false) { //NB: Needs $top > 68 //print out totals for current extension if($grand_total) { $totals_label = 'Grand Total:'; } else { $totals_label = 'Totals:'; } if($total_calls==0) { $totals_line1 = array($totals_label,'',$total_duration.' s',sprintf("%.3f",$total_cost)." (excl. VAT)"); } else { if($total_calls==1) { $totals_line1 = array($totals_label,$total_calls.' call',$total_duration.' s',sprintf("%.3f",$total_cost)." (excl. VAT)"); } else { $totals_line1 = array($totals_label,$total_calls.' calls',$total_duration.' s',sprintf("%.3f",$total_cost)." (excl. VAT)"); } } $totals_line2 = array('','',createTimeString($total_duration),sprintf("%.3f",$total_cost*$VAT)." (incl. VAT)"); $top=$top-LINESPACE-LINESPACE; $page->drawLine(0, $top, WIDTH, $top); $top=$top-FONTSIZE-LINESPACE; DrawColumn($totalcols,$totals_line1,$page,$top,$font,$boldfont,true); $top=$top-FONTSIZE-LINESPACE; DrawColumn($totalcols,$totals_line2,$page,$top,$font,$boldfont,true); $top=$top-LINESPACE-LINESPACE; $page->drawLine(0, $top, WIDTH, $top); } function displaySummary(&$summary,&$page,&$top,$font,$boldfont,$VAT = false) { //NB: Needs $top > //setup formatting $headings = array('Call Type','Calls','Duration','Cost'); $cols = array(150,35,75); //headings for summary $top=$top-LINESPACE-LINESPACE; $page->drawLine(0, $top, WIDTH, $top); $top=$top-FONTSIZE-LINESPACE; DrawColumn($cols,$headings,$page,$top,$font,$boldfont,true); $top=$top-LINESPACE-LINESPACE; $page->drawLine(0, $top, WIDTH, $top); $totals = array_pop($summary); foreach($summary as $line) { if($VAT !== false) { $cost = $line['total_cost'] * $VAT; } else { $cost = $line['total_cost']; } $data = array( $line['name'], $line['total_calls'], createTimeString($line['total_sec']), sprintf("%.3f",$cost) ); $top=$top-FONTSIZE-LINESPACE; DrawColumn($cols,$data,$page,$top,$font,$boldfont,false); } //draw totals row if($VAT !== false) { $cost = $totals['total_cost'] * $VAT; } else { $cost = $totals['total_cost']; } $data = array( $totals['name'], $totals['total_calls'], createTimeString($totals['total_sec']), sprintf("%.3f",$cost) ); $top=$top-FONTSIZE-LINESPACE; DrawColumn($cols,$data,$page,$top,$font,$boldfont,true); $top=$top-LINESPACE-LINESPACE; $page->drawLine(0, $top, WIDTH, $top); } function process_data($args) { global $tpl; global $ini; global $db; global $LU; global $LUA; global $debug; global $extensions; global $group_name; //print_r($args); //{{{ initialisation $query_debug = false; $routeField = $ini['System']['routing_field']; $localCode = $ini['Calls']['local_area']; $tagging_enabled = $ini['Tagging']['enabled']; $print_summary=false; $separate_extensions = false; $channel = array(); $zero_cost_channel_str = $ini['ZeroCost']['channels']; $in_channel_str = $ini['Incoming']['channels_in']; $showTPLTotals = false; $ast_tbl = $ini['DB']['cdr_table']; $src_changed = false; //flag used to detect whether to change the output of the display for the call source $headings_changed = false; //flag used to enforce heading changes - see thusa trac ticket #150 //cache phone list and phone book $phone_list = array(); $phone_book = array(); cacheNumbers($db,$phone_list,$phone_book); //{{{ get out channel_str foreach($ini['Billing'] as $section=>$enabled) { if($enabled) { $out_channels[] = $ini['Translation'][$section]; //this is changed depending on each asterisk setup, in the config file } } $out_channel_str = implode(',',$out_channels); //}}} $subtitle=false; $type_sql =''; $target_sql = ''; $csv = false; $pdf = false; if(!isset($args['maxEntries'])) { $limit = 0; } else { $limit = intval($args['maxEntries']); } if(!isset($args['perPage'])) { $tpl->assign('pagerows',$ini['System']['per_page']); } else { $tpl->assign('pagerows',intval($args['perPage'])); } //{{{ get extension array for the queries that need it if($LU->checkRight(VIEW_ALL_EXT)) { if(isset($args['extList'])&&!empty($args['extList'])) { $extension_array = explode(',',$args['extList']); $ext_range = $args['extList']; } else { if(isset($args['groupSelect'])&&!empty($args['groupSelect'])) { // echo $args['groupSelect']; $filters = array('filters'=>array('group_id'=>$args['groupSelect'])); $group = $LUA->perm->getGroups($filters); $extensions = $group['0']['extensions']; $extension_array = explode(',',$extensions); $ext_range = $group['0']['group_define_name']; } else { //we need to get the extension array from the db $ext_query="SELECT DISTINCT `user_phone` FROM `liveuser_users` WHERE `user_phone`<>'' ORDER BY `user_phone` ASC"; $ext_res = $db->query($ext_query); if(handleError($ext_res)) { $extension_array = array(); while($ext_res->fetchInto($ext_row)) { $extension_array[] = $ext_row['user_phone']; } $ext_range = "All"; } } } } else { if($LU->checkRight(GROUP_STATS)) { //use the $extensions variable defined in initialisation.inc.php $extension_array = explode(",",$extensions); $ext_range = $group_name; } else { $extension_array[] = $LU->getProperty('user_phone'); $ext_range = $LU->getProperty('user_phone'); } } $quote_func = create_function('&$item,$key','$item = "\'".trim($item)."\'";'); array_walk($extension_array, $quote_func); $extension_str = implode(',',$extension_array); //}}} $query =''; //{{{ cache extension cost multipliers $fiddle_sql = "SELECT user_phone, user_cost_multiplier FROM liveuser_users WHERE user_cost_multiplier <> 1 AND user_phone IN ($extension_str)"; $fiddle_res = $db->query($fiddle_sql); if(handleError($fiddle_res)) { $extension_costs_array = array(); while($fiddle_res->fetchInto($fid_row)) { $extension_costs_array[$fid_row['user_phone']] = $fid_row['user_cost_multiplier']; } } //}}} if(isset($args['csv_export'])&&!empty($args['csv_export'])) { $csv = true; } else { if(isset($args['pdf_export'])&&!empty($args['pdf_export'])) { $pdf = true; if(isset($args['pdf_extension'])&&!empty($args['pdf_extension'])) { $separate_extensions = true; $subtitle = true; } } } if(isset($args['targetSelect'])&&!empty($args['targetSelect'])) { $target = $args['targetSelect']; switch($target) { case '1': //Incoming $target_sql = " AND (`$routeField` IN ($in_channel_str)) "; $target_hdr = 'Incoming'; $incoming = true; $outgoing = false; $src_field = 'src'; $extra_sql = ''; break; case '2': //Outgoing $target_sql = " AND (`$routeField` IN ($out_channel_str)) "; $target_hdr = 'Outgoing'; $outgoing = true; $incoming = false; $src_field = 'src'; $extra_sql = ''; break; case '3': //Outgoing[PIN] $target_sql = " AND (`$routeField` IN ($out_channel_str)) "; $target_hdr = 'Outgoing[PIN]'; $outgoing = true; $incoming = false; $src_changed = true; $src_field = 'accountcode'; $extra_sql = " AND accountcode IS NOT NULL "; $tpl->assign('showAccountCode','true'); $tpl->assign('hideSrc','true'); break; case '4': //Outgoing[Cost Centre] $src_changed = true; $target_sql = " AND (`$routeField` IN ($out_channel_str)) "; $target_hdr = 'Outgoing[Cost Centre]'; $outgoing = true; $incoming = false; $src_field = 'accountcode'; $extra_sql = " AND accountcode IS NOT NULL "; $tpl->assign('show_amaflags','true'); $tpl->assign('hideSrc','true'); //$src_field = 'amaflags'; //$extra_sql = " AND amaflags IS NOT NULL AND amaflags <> '3'"; break; } } else { //technically should be a combination of the above 2 options, but is left out for efficiency $target_sql = ''; $target_hdr = 'Incoming, Outgoing'; $target = 0; } if(isset($args['typeSelect'])) { //we need to get the extension array from the db $ext_query="SELECT DISTINCT(`user_phone`) FROM `liveuser_users` WHERE `user_phone`<>'' ORDER BY `user_phone` ASC"; $ext_res = $db->query($ext_query); if(handleError($ext_res)) { $all_extension_array = array(); while($ext_res->fetchInto($ext_row)) { $all_extension_array[] = "'".$ext_row['user_phone']."'"; } $all_ext_str = implode(',',$all_extension_array); $type = $args['typeSelect']; switch ($type) { case '1' : //Internal //$type_sql = " AND (src IN ($all_ext_str) AND dst IN ($all_ext_str)) "; $type_sql = " AND (src IN ($ext_query) AND dst IN ($ext_query)) "; $target_sql= " AND `$routeField` IN ($zero_cost_channel_str) "; // in/out routing channels mean nothing for internal calls $type_hdr = 'Internal'; break; case '2' : //External //$type_sql = " AND (src IN ($all_ext_str) XOR dst IN ($all_ext_str)) "; $type_sql = " AND (src IN ($ext_query) XOR dst IN ($ext_query)) "; $type_hdr = 'External'; break; default: $type_sql = " AND (src IN ($ext_query) OR dst IN ($ext_query)) "; $target_sql = substr($target_sql, 0, -2); //take out last bracket $target_sql.= " OR `$routeField` IN ($zero_cost_channel_str)) "; $type_hdr = 'Internal, External'; } } else { $type_sql =''; $type_hdr = 'Internal, External'; } //echo "TYPE: $type"; } else { $type = 0; //technically the sql should be "(src IN ($all_ext_str) OR dst IN ($all_ext_str))" //but that will increase the processing too much on an already insane sql statement $type_sql =''; $type_hdr = 'Internal, External'; } //}}} //{{{ create date values if(isset($args['submitMonth'])&&'Submit Month Only'==$args['submitMonth']&&isset($args['dateMonthView'])) { // {{{ create date values $dateFrom = date("Y-m-d H:i:s",mktime(0,0,0,$args['dateMonthView']['m'],1,$args['dateMonthView']['Y'])); $dateTo = date("Y-m-d H:i:s",mktime(0,0,0,$args['dateMonthView']['m']+1,1,$args['dateMonthView']['Y'])); // }}} $tpl->assign('dateMonth','true'); $tpl->assign('date_year',$args['dateMonthView']['Y']); $tpl->assign('date_month',$args['dateMonthView']['m']); } else { if(isset($args['submitDate'])&&'Submit Date Range'==$args['submitDate']&&isset($args['dateFrom'])&&isset($args['dateTo'])) { $dateFrom = date("Y-m-d H:i:s",mktime(0,0,0,$args['dateFrom']['m'],$args['dateFrom']['d'],$args['dateFrom']['Y'])); $dateTo = date("Y-m-d H:i:s",mktime(0,0,-1,$args['dateTo']['m'],$args['dateTo']['d']+1,$args['dateTo']['Y'])); $tpl->assign('dateRange','true'); $tpl->assign('dateFrom',$dateFrom); $tpl->assign('dateTo',$dateTo); } } if(isset($args['dateFrom'])&&isset($args['dateTo'])&&(isset($args['submitCSV'])||isset($args['submitPDF']))) { $dateFrom = $args['dateFrom']; $dateTo = $args['dateTo']; } //}}} $tpl->assign('show_main','false'); switch ($args['action']) { case '1': //'most_longest' : //set filename for csv/pdf report $filename='Longest Calls '.date("Ymd"); if($pdf&&$separate_extensions) { $subtitle=true; $query="SELECT `calldate`,`$src_field`,`dst`,`gpb_type` AS `dest_type`,`billsec`,`cost` FROM `$ast_tbl` LEFT JOIN global_phone_book ON (dst = gpb_number) WHERE `cdr_id` IN ( SELECT `cdr_id` FROM `$ast_tbl` WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND `src` IN ($extension_str) AND `cost` >='0'"; $query.=$type_sql; $query.=$target_sql; $query.=$extra_sql; if($incoming) { $group_by = 'dst'; $query.=") ORDER BY `dst` ASC, `billsec` DESC"; } else { $group_by = $src_field; $query.=") ORDER BY `$src_field` ASC, `billsec` DESC"; } //column headings $coldata = array('Call Time', 'Source', 'Destination', 'Dest. Type', 'Duration','Cost'); $result_data=array('calldate',$src_field,'dst','dest_type','billsec','cost'); $cols=array(125, 100, 150, 70, 75); $subcols=array(50, 400); } else { $subtitle=false; $query = "SELECT `calldate`,`$src_field`,`dst`,`gpb_type` AS `dest_type`,`billsec`,`cost` FROM `$ast_tbl` LEFT JOIN global_phone_book ON (dst = gpb_number) WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND (`src` IN ($extension_str) OR `dst` IN ($extension_str)) AND `cost` >='0'"; $query.= $type_sql; $query.= $target_sql; $query.= $extra_sql; $query.= "ORDER BY `billsec` DESC "; if(!empty($limit)) { $query.= "LIMIT $limit"; } //column headings $coldata = array('Call Time', 'Source', 'Destination', 'Dest. Type', 'Duration','Cost'); $result_data=array('calldate',$src_field,'dst','dest_type','billsec','cost'); $cols=array(125, 100, 150, 70, 75); $subcols=array(50, 400); $subdata = ''; } //echo $query; $tpl->assign('show_longest','true'); //{{{ pdf styling options // Report Heading $hdrdata=array( 'heading' => 'Longest Calls Report', 'title' => 'Extension Range', 'title_val' => $ext_range, 'type' => $type_hdr, 'target' => $target_hdr); //$separate_extensions = false; $print_totals=true; $totalcols=array(300,75,75); //}}} break; case '2' : //'most_expensive' : $target_sql = " AND `$routeField` IN ($out_channel_str) "; if(!$src_changed) { $target_hdr = 'Outgoing'; $outgoing = true; $incoming = false; } $filename='Most Expensive Calls '.date("Ymd"); if($pdf&&$separate_extensions) { $subtitle=true; $query=''; $group_by = $src_field; $query="SELECT `calldate`,`$src_field`,`dst`,`gpb_type` AS `dest_type`,`billsec`,`cost` FROM `$ast_tbl` LEFT JOIN global_phone_book ON (dst = gpb_number) WHERE `cdr_id` IN ( SELECT `cdr_id` FROM `$ast_tbl` WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND `src` IN ($extension_str) AND `cost` >='0'"; $query.=$type_sql; $query.=$target_sql; $query.= $extra_sql; $query.=") ORDER BY `$src_field` ASC, `billsec` DESC"; //column headings $coldata = array('Call Time', 'Destination', 'Dest. Type', 'Duration(sec)','Cost'); $result_data=array('calldate','dst','dest_type','billsec','cost'); $cols=array(125, 150, 70, 75); $subcols=array(50, 400); } else { $subtitle=false; $query = "SELECT `calldate`,`$src_field`,`dst`,`gpb_type` AS `dest_type`,`billsec`,`cost` FROM `$ast_tbl` LEFT JOIN global_phone_book ON (dst = gpb_number) WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND `src` IN ($extension_str) AND `cost` >='0'"; $query.= $type_sql; $query.= $target_sql; $query.= $extra_sql; $query.= "ORDER BY `cost` DESC "; if(!empty($limit)) { $query.= "LIMIT $limit"; } $subdata = ''; //column headings $coldata = array('Call Time', 'Source', 'Destination', 'Dest. Type', 'Duration','Cost'); $result_data=array('calldate',$src_field,'dst','dest_type','billsec','cost'); $cols=array(125, 100, 150, 70, 75); $subcols=array(50, 400); } //$query = "SELECT `$routeField`,`calldate`,`$src_field`,`dst`,`billsec`,`cost` FROM `$ast_tbl` WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' ORDER BY `cost` DESC LIMIT $limit"; $tpl->assign('show_expensive','true'); $tpl->assign('showTotals','true'); //{{{ pdf styling options // Report Heading $hdrdata=array( 'heading' => 'Most Expensive Calls Report', 'title' => 'Extension Range', 'title_val' => $ext_range, 'type' => $type_hdr, 'target' => 'Outgoing'); $print_totals=true; $totalcols=array(300,75,75); //}}} break; case '12' : // Aggregated Detailed Call Report $filename='Detailed Bill '.date("Ymd"); // Report Heading $hdrdata=array( 'heading' => 'Detailed Billing Report', 'title' => 'Extension Range', 'title_val' => $ext_range, 'type' => $type_hdr, 'target' => $target_hdr); $headings_changed = true; case '3' : //'most_dialled' : //incoming/outgoing should NOT apply here but internal/external might $target_sql = " AND `$routeField` IN ($out_channel_str) "; if(!$src_changed) { //source hasn't been changed to an outgoing field so force it here $target_hdr = 'Outgoing'; if($pdf&&$separate_extensions) { $print_summary=true; } } else { $print_summary = false; } if(!$headings_changed) { $filename='Most Dialled '.date("Ymd"); // Report Heading $hdrdata=array( 'heading' => 'Most Dialled Numbers Report', 'title' => 'Extension Range', 'title_val' => $ext_range, 'type' => $type_hdr, 'target' => $target_hdr); } $tpl->assign('heading',$hdrdata['heading']); $outgoing = true; $incoming = false; if($pdf&&$separate_extensions) { $subtitle=true; $query=''; $group_by = $src_field; $query="SELECT `$src_field`,`dst`,`gpb_type` AS `dest_type`,COUNT(`dst`) AS `dst_count`, SUM(`cost`) AS `total_cost`, SUM(`billsec`) AS `total_billsec` FROM `$ast_tbl` LEFT JOIN global_phone_book ON (dst = gpb_number) WHERE `cdr_id` IN ( SELECT `cdr_id` FROM `$ast_tbl` WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND `src` IN ($extension_str) AND `cost` >='0'"; $query.=$type_sql; $query.=$target_sql; $query.= $extra_sql; $query.=") GROUP BY `$src_field`,`dst` ORDER BY `$src_field` ASC, `dst_count` DESC"; } else { $print_summary=false; $subtitle=false; $query = "SELECT `dst`,`gpb_type` AS `dest_type`, COUNT(`dst`) AS `dst_count`, SUM(`cost`*`user_cost_multiplier`) AS `total_cost`, SUM(`billsec`) AS `total_billsec` FROM `$ast_tbl` JOIN liveuser_users on (src = user_phone) LEFT JOIN global_phone_book ON (dst = gpb_number) WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND `src` IN ($extension_str) AND `cost`>='0'"; $query.= $type_sql; $query.= $target_sql; $query.= $extra_sql; $query.=" GROUP BY `dst` ORDER BY `dst_count` DESC, `total_cost` DESC "; if(!empty($limit)) { $query.="LIMIT $limit"; } $subdata = ''; } $tpl->assign('show_most_dialled','true'); $tpl->assign('hideSrc','true'); $tpl->assign('hideCost','true'); $tpl->assign('showTotals','true'); $tpl->assign('showTotalCost','true'); $tpl->assign('showTotalBillsec','true'); $tpl->assign('hideBillSec','true'); //{{{ pdf styling options //column headings $coldata = array('Destination', 'Dest. Type', 'Times Dialled', 'Total Duration', 'Total Cost'); $result_data=array('dst','dest_type','dst_count','total_billsec', 'total_cost'); $cols=array(150, 70, 100, 100); $subcols=array(50, 400); //$separate_extensions = false; $print_totals=true; $totalcols=array(245,75,100); //}}} break; case '4' : //'busy_hours' : //TODO: This graph needs to run off the extension_str so that it applies to a group/individual as well //we do not want a csv or pdf output of our query $csv = false; $pdf = false; require_once 'jpgraph/jpgraph.php'; require_once 'jpgraph/jpgraph_line.php'; //$days = getDayDiff($dateFrom,$dateTo); //{{{ get date portion of datetimes $df = explode(' ',$dateFrom); $df = $df[0]; $dt = explode(' ',$dateTo); $dt = $dt[0]; //}}} $df = explode('-',$df); $dt = explode('-',$dt); $datefromTS = mktime(0,0,0,$df[1],$df[2],$df[0]); $datetoTS = mktime(0,0,0,$dt[1],$dt[2],$dt[0]); $days = weekdaysBetween($datefromTS,$datetoTS); /*if($debug) { echo "DFTS: $datefromTS | DTTS: $datetoTS
"; echo "DF: ".date("Y-m-d",$datefromTS)." | DT: ".date("Y-m-d",$datetoTS)."
"; echo "Days: $days"; }*/ $in_query = "SELECT `calldate` FROM `$ast_tbl` WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `$routeField` IN ($in_channel_str) AND `disposition`='ANSWERED'"; $out_query = "SELECT `calldate` FROM `$ast_tbl` WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `$routeField` IN ($out_channel_str) AND `disposition`='ANSWERED'"; $in_res = $db->query($in_query); $out_res = $db->query($out_query); if(handleError($in_res)&&handleError($out_res)) { $in_data = array(); $out_data = array(); while ($in_res->fetchInto($in_row)) { $hour = getHour($in_row['calldate']); $in_data[] = $hour; } while ($out_res->fetchInto($out_row)) { $hour = getHour($out_row['calldate']); $out_data[] = $hour; } $in_data = array_count_values($in_data); for($i=0;$i<24;$i++) { if(isset($in_data[$i])) { //we need to divide the number of calls by the number of days if(0!=$days) { $in_data[$i] /= $days; } } else { $in_data[$i] = 0; } } $out_data = array_count_values($out_data); for($i=0;$i<24;$i++) { if(isset($out_data[$i])) { //divide data by number of days if(0!=$days) { $out_data[$i] /= $days; } } else { $out_data[$i] = 0; } } /*echo "IN:
"; print_r($in_data); echo "
OUT:
"; print_r($out_data);*/ //{{{ setup graph $timestamp = microtime(); $graphname = "tmp/busy_hours$timestamp.jpg"; $jpgcache = APACHE_CACHE_DIR; //}}} //{{{ create graph $graph = new graph(800, 400, $graphname, 0, true); $graph->img->SetMargin(50, 30, 30, 50); $graph->SetScale('textlin'); $graph->yaxis->SetLabelAngle(0); $graph->yaxis->title->Set('Average Calls'); $graph->xaxis->SetLabelAngle(0); $graph->xaxis->title->Set('Hour of Day'); $line_in = new LinePlot($in_data); $line_in->SetColor('orange'); $line_in->SetLegend('Incoming Calls'); $line_in-> mark->SetType(MARK_X); $line_out = new LinePlot($out_data); $line_out->SetColor('blue'); $line_out->SetLegend('Outgoing Calls'); $line_out-> mark->SetType(MARK_X); $graph->Add($line_in); $graph->Add($line_out); $graph_handle = $graph->Stroke($graphname); //}}} $tpl->assign('show_busy_hours','true'); $tpl->assign('graph_name',$graphname); } //NB: We do not want to execute another query, so assign $query an empty string $query=''; break; case '5': //pdf detailed bill $filename='Detailed Bill '.date("Ymd"); $query=''; //{{{ create query if($pdf&&$separate_extensions) { $query="SELECT `calldate`,`$src_field`,`dst`,`gpb_type` AS `dest_type`,`billsec`,`cost` FROM `$ast_tbl` LEFT JOIN global_phone_book ON (dst = gpb_number) WHERE `cdr_id` IN ( SELECT `cdr_id` FROM `$ast_tbl` WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND `cost` >='0'"; $query.=$type_sql; $query.=$target_sql; $query.= $extra_sql; if($incoming) { $query.="AND `dst` IN ($extension_str) ) ORDER BY `dst` ASC, `calldate` ASC"; $coldata = array('Call Time', 'Source','Duration','Cost'); $result_data=array('calldate',$src_field,'billsec','cost'); $cols=array(125, 100, 75); $print_summary=false; $group_by = 'dst'; } else { $query.="AND `src` IN ($extension_str) ) ORDER BY `$src_field` ASC, `calldate` ASC"; $coldata = array('Call Time', 'Destination', 'Dest. Type', 'Duration','Cost'); $result_data=array('calldate','dst','dest_type','billsec','cost'); $cols=array(125, 150, 70, 75); $print_summary=true; $group_by = $src_field; } $subcols=array(50, 400); $print_totals = true; $totalcols=array(320,75,75); $subtitle=true; } else { $query .= "SELECT calldate,$src_field,dst,gpb_type AS dest_type,billsec,cost FROM `$ast_tbl` LEFT JOIN global_phone_book ON (dst = gpb_number) WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND `cost` >='0'"; if($incoming) { $query.=" AND `dst` IN ($extension_str)"; } else { $query.=" AND `src` IN ($extension_str)"; } if(!empty($type_sql)) { $query.= $type_sql; } if(!empty($target_sql)) { $query.= $target_sql; } $query.= $extra_sql; $query.="ORDER BY calldate ASC"; //echo $query; //get rid of notices for lack of separate extensions $subcols = ''; $subdata = ''; $print_summary=false; //$print_totals = false; $print_totals=true; $totalcols=array(320,75,75); $coldata = array('Call Time', 'Source', 'Destination', 'Dest. Type', 'Duration','Cost'); $result_data=array('calldate',$src_field,'dst','dest_type','billsec','cost'); $cols=array(125, 100, 150, 70, 75); $subcols=array(50, 400); } //}}} $tpl->assign('show_phone_data','true'); //{{{ pdf styling options // Report Heading $hdrdata=array( 'heading' => 'Detailed Billing Report', 'title' => 'Extension Range', 'title_val' => $ext_range, 'type' => $type_hdr, 'target' => $target_hdr); //$separate_extensions = true; //$subtitle = true; //}}} //} break; case '6': //Group Statistics //NB: THIS REPORT CANNOT HAVE ITS SOURCE CHANGED! //if($LU->checkRight(ADMIN)) { $filename='Group Statistics '.date("Ymd"); $pdf = true; if(isset($args['chkShowVAT'])&&!empty($args['chkShowVAT'])) { $VAT = $ini['System']['vat_multiplier']; } else { $VAT = false; } //we do not want to execute a query $query = ''; //column layout $coldata = array(''); $result_data=array(''); $cols=array(); if($pdf&&$separate_extensions) { $subtitle=true; $print_summary=true; $subcols=array(50, 400); $print_totals = true; $totalcols=array(320,75,75); } else { //get rid of notices for lack of separate extensions $subcols = ''; $subdata = ''; } //$tpl->assign('show_phone_data','true'); //{{{ pdf styling options // Report Heading $hdrdata=array( 'heading' => 'Group Statistics Report', 'title' => 'Extension Range', 'title_val' => $ext_range, 'target' => 'Outgoing'); //$separate_extensions = true; //$subtitle = true; //}}} //common PDF initialisation $font = Zend_Pdf_font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA); $boldfont = Zend_Pdf_font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA_BOLD); //{{{ setup pdf document - code courtesy of Sean Preston $pdf = new Zend_Pdf(); // Reverse the page adding order $pdf->pages = array_reverse($pdf->pages); $page = ''; // Setup the page style $style = new Zend_Pdf_Style(); $style->setFont($font, FONTSIZE); $page_num = 0; $row_num = 0; $ext_page_num = 0; //{{{ modify date values for printing $showDateFrom = explode(' ',$dateFrom); $showDateFrom = $showDateFrom[0]; $hdrdata['fromDate'] = $showDateFrom; $showDateTo = explode(' ',$dateTo); $showDateTo = $showDateTo[0]; $hdrdata['toDate'] = $showDateTo; //}}} $grand_total = array( 'international' => array('name'=>$ini['Output']['international'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'national' => array('name'=>$ini['Output']['national'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'local' =>array('name'=>$ini['Output']['local'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'fallback' => array('name'=>$ini['Output']['fallback'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'toll_free' =>array('name'=>$ini['Output']['toll_free'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'special' => array('name'=>$ini['Output']['special'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'vodacom' =>array('name'=>$ini['Output']['vodacom'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'mtn' => array('name'=>$ini['Output']['mtn'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'cellc' =>array('name'=>$ini['Output']['cellc'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'incoming' => array('name'=>$ini['Output']['incoming'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0) ); if(!$tagging_enabled) { $grand_total['shared'] = array('name'=>$ini['Output']['shared'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0); } //make sure that the total row is the last in the set $grand_total['total'] = array('name'=>"Grand Totals",'total_calls'=>0,'total_sec'=>0,'total_cost'=>0); foreach($extension_array as $ext) { //get rid of quotes $ext = trim($ext,"'"); $summary = fetchSummary($ext,'src',$db,$ini,$grand_total,$dateFrom,$dateTo); if($separate_extensions && !empty($summary['total']['total_calls'])) { //find name(alias) of new extension $name_query="SELECT user_alias FROM liveuser_users WHERE user_phone = '$ext'"; $name_res = $db->query($name_query); if(handleError($name_res)) { if($name_res->numRows()>0) { $name_res->fetchInto($name_row); if(!empty($name_row['user_alias'])) { $old_name = $name_row['user_alias']; } else { $old_name = ''; } } else { $old_name = ''; } } //find name of department(group) that the extension belongs to $dep_query = "SELECT group_define_name FROM liveuser_groups WHERE extensions LIKE '%"."$ext"."%'"; $dep_data = $db->getAll($dep_query); if(handleError($dep_data)) { if(!empty($dep_data)) { $dep_string=''; foreach($dep_data as $dep_row) { if(strlen($dep_string)+strlen($dep_row['group_define_name'])<100) { $dep_string .= $dep_row['group_define_name'].', '; } } //remove last comma $dep_string=substr($dep_string,0,-2); } else { $dep_string = ''; } } // Sub heading data $subdata=array($ext, $old_name, $dep_string); //add a new page $page = newPDFPage($pdf,$style,$top,$row_num,$page_num,$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT); displaySummary($summary,$page,$top,$font,$boldfont,$VAT); } } //{{{ now do final page with totals on it $subdata = array('Grand Totals'); $subcols = array(); $page = newPDFPage($pdf,$style,$top,$row_num,$page_num,$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT); displaySummary($grand_total,$page,$top,$font,$boldfont,$VAT); //}}} //{{{ send pdf $pdf_string = $pdf->render(); //send headers $filename.= '.pdf'; header('Content-type: application/pdf'); header('Content-Length: ' . strlen($pdf_string)); header('Content-Disposition: attachment; filename="' . $filename . '"'); echo $pdf_string; die(); //}}} //}}} break; case '7': //Contact report $filename='Contact Report '.date("Ymd"); $subtitle = false; //{{{ formulate sql query if($pdf&&$separate_extensions) { $gpb_numbers = array_keys($phone_book); $query = ''; if($incoming) { foreach($gpb_numbers as $gpb_num) { $query.= "(SELECT `$routeField`,`calldate`,`$src_field`,`dst`,`billsec`,`cost` FROM `$ast_tbl` JOIN global_phone_book ON (src = gpb_number) WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND `dst` IN ($extension_str) AND `src` = '$gpb_num'"; if(!empty($args['contactSelect'])) { $query.= "AND `gpb_type` = '".$args['contactSelect']."'"; } $query.= $type_sql; $query.= $target_sql; $query.= $extra_sql; $query.= "ORDER BY `calldate` ASC "; if(!empty($limit)) { $query.= "LIMIT $limit"; } $query.= ") UNION"; } $group_by = 'src'; } else { foreach($gpb_numbers as $gpb_num) { $query.= "(SELECT `$routeField`,`calldate`,`$src_field`,`dst`,gpb_type AS dest_type,`billsec`,`cost` FROM `$ast_tbl` JOIN global_phone_book ON (dst = gpb_number) WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND `src` IN ($extension_str) AND `dst` = '$gpb_num'"; if(!empty($args['contactSelect'])) { $query.= "AND `gpb_type` = '".$args['contactSelect']."'"; } $query.= $type_sql; $query.= $target_sql; $query.= $extra_sql; $query.= "ORDER BY `calldate` ASC "; if(!empty($limit)) { $query.= "LIMIT $limit"; } $query.= ") UNION"; } $group_by = 'dst'; } $query = substr($query,0,-6); //echo $query; } else { if($incoming) { $query = "SELECT `$routeField`,`calldate`,`src`,`dst`,`billsec`,`cost` FROM `$ast_tbl` JOIN global_phone_book ON (src = gpb_number) WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND `dst` IN ($extension_str)"; if(!empty($args['contactSelect'])) { $query.= "AND `gpb_type` = '".$args['contactSelect']."'"; } $query.= $type_sql; $query.= $target_sql; $query.= $extra_sql; $query.= "ORDER BY `src`,`calldate` ASC "; } else { $query = "SELECT `$routeField`,`calldate`,`$src_field`,`dst`,gpb_type AS dest_type,`billsec`,`cost` FROM `$ast_tbl` JOIN global_phone_book ON (dst = gpb_number) WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND `src` IN ($extension_str)"; if(!empty($args['contactSelect'])) { $query.= "AND `gpb_type` = '".$args['contactSelect']."'"; } $query.= $type_sql; $query.= $target_sql; $query.= $extra_sql; $query.= "ORDER BY `dst`,`calldate` ASC "; } if(!empty($limit)) { $query.= "LIMIT $limit"; } } //echo $query; //}}} // Report Heading if($pdf&&$separate_extensions) { $subtitle=true; $subcols=array(100, 300); if($incoming) { $coldata = array('Call Time', 'Destination', 'Duration'); $result_data=array('calldate','dst','billsec'); $cols=array(125, 150); $incoming = false; // SLIGHT HACK TO GET PDF TO DISPLAY BASED ON CLIENT RATHER THAN RECEIVER } else { $coldata = array('Call Time', 'Source', 'Duration', 'Cost'); $result_data=array('calldate',$src_field,'billsec','cost'); $cols=array(125, 150, 75); $incoming = true; // SLIGHT HACK TO GET PDF TO DISPLAY BASED ON CLIENT RATHER THAN SOURCE } } else { $coldata = array('Call Time', 'Source', 'Destination', 'Duration', 'Cost'); $result_data=array('calldate',$src_field,'dst','billsec','cost'); $cols=array(125, 100, 150, 100); $subcols=array(50, 400); //get rid of notices for lack of separate extensions $subcols = ''; $subdata = ''; } $print_summary=false; //$print_totals = false; $print_totals=true; $totalcols=array(320,75,75); $hdrdata=array( 'heading' => 'Contact Report', 'title' => 'Extension Range', 'title_val' => $ext_range, 'type' => $type_hdr, 'target' => $target_hdr); $tpl->assign('show_contact','true'); break; case '11': // Cost Centre / amaflags report $filename='Cost Centre Report '.date("Ymd"); $hdrdata=array( 'heading' => 'Cost Centre Report', 'title' => 'Extension Range', 'title_val' => $ext_range, 'type' => $type_hdr, 'target' => $target_hdr); $coldata = array('Cost Centre','Call Time', 'Source', 'Destination', 'Duration', 'Cost'); $headings_changed = true; case '8': // Username/pincode report $print_totals=true; $totalcols=array(320,75,75); if(!$headings_changed) { $filename='Username Report '.date("Ymd"); $hdrdata=array( 'heading' => 'Username Report', 'title' => 'Extension Range', 'title_val' => $ext_range, 'type' => $type_hdr, 'target' => $target_hdr); $coldata = array('Username','Call Time', 'Source', 'Destination', 'Duration', 'Cost'); } $tpl->assign('heading',$hdrdata['heading']); $subtitle = false; $target_sql = " AND `$routeField` IN ($out_channel_str) "; $target_hdr = 'Outgoing'; $outgoing = true; $incoming = false; $query = ''; if($pdf&&$separate_extensions) { $group_by = 'accountcode'; $subtitle = true; //TODO: get distinct accountcodes from db $acc_query = "SELECT distinct accountcode FROM `$ast_tbl` WHERE accountcode IS NOT NULL order by accountcode"; $acc_rows = $db->getAll($acc_query); if(handleError($acc_rows)) { //take out the blank string - accountcode array_shift($acc_rows); foreach($acc_rows as $acc) { //formulate query $query.= "(SELECT `$routeField`,`accountcode`,`calldate`,`src`,`dst`,`billsec`,`cost` FROM `$ast_tbl` LEFT JOIN global_phone_book ON (dst = gpb_number) WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND `src` IN ($extension_str) AND `cost` >='0' AND `accountcode` = '".$acc['accountcode']."' "; $query.= $type_sql; $query.= $target_sql; $query.= "ORDER BY `accountcode` ASC,`calldate` ASC "; if(!empty($limit)) { $query.= "LIMIT $limit"; } $query.=") UNION"; } $query = substr($query,0,-6); } $coldata = array('Call Time', 'Source', 'Destination', 'Duration','Cost'); $result_data=array('calldate','src','dst','billsec','cost'); $cols=array(125, 70, 150, 75); $subcols=array(50, 400); $totalcols=array(320,75,75); $subdata = ''; } else { $tpl->assign('showAccountCode','true'); $query.= "SELECT `$routeField`,`accountcode`,`calldate`,`src`,`dst`,`billsec`,`cost` FROM `$ast_tbl` LEFT JOIN global_phone_book ON (dst = gpb_number) WHERE `calldate` > '$dateFrom' AND `calldate` < '$dateTo' AND `disposition`='ANSWERED' AND `cost` >='0' AND `accountcode` <> '' AND `src` IN ($extension_str) "; $query.= $type_sql; $query.= $target_sql; $query.= "ORDER BY `accountcode` ASC,`calldate` ASC "; if(!empty($limit)) { $query.= "LIMIT $limit"; } $result_data=array('accountcode','calldate','src','dst','billsec','cost'); $cols=array(100, 125, 100, 150, 100); $subcols=array(50, 400); //get rid of notices for lack of separate extensions $subcols = ''; $subdata = ''; } //echo $query; $print_totals=true; $totalcols=array(300,75,75); $tpl->assign('show_pincode','true'); break; case '9': //Department Group Statistics Report //if($LU->checkRight(ADMIN)) { $filename='Department Summary '.date("Ymd"); $pdf = true; //sort of a hack, the groups are being substituted as 'extensions', we want each dept shown $separate_extensions = true; if(isset($args['chkShowVAT'])&&!empty($args['chkShowVAT'])) { $VAT = $ini['System']['vat_multiplier']; } else { $VAT = false; } //we do not want to execute a query $query = ''; //column layout $coldata = array(''); $result_data=array(''); $cols=array(); $subcols=array(50, 400); $subtitle=true; $print_summary=true; $print_totals = true; $totalcols=array(320,75,75); //{{{ pdf styling options // Report Heading $hdrdata=array( 'heading' => 'Department Summary Report', 'title' => 'Extension Range', 'title_val' => $ext_range, 'target' => 'Outgoing'); //}}} //common PDF initialisation $font = Zend_Pdf_font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA); $boldfont = Zend_Pdf_font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA_BOLD); //{{{ setup pdf document - code courtesy of Sean Preston $pdf = new Zend_Pdf(); // Reverse the page adding order $pdf->pages = array_reverse($pdf->pages); $page = ''; // Setup the page style $style = new Zend_Pdf_Style(); $style->setFont($font, FONTSIZE); $page_num = 0; $row_num = 0; $ext_page_num = 0; //{{{ modify date values for printing $showDateFrom = explode(' ',$dateFrom); $showDateFrom = $showDateFrom[0]; $hdrdata['fromDate'] = $showDateFrom; $showDateTo = explode(' ',$dateTo); $showDateTo = $showDateTo[0]; $hdrdata['toDate'] = $showDateTo; //}}} $grand_total = array( 'international' => array('name'=>$ini['Output']['international'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'national' => array('name'=>$ini['Output']['national'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'local' =>array('name'=>$ini['Output']['local'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'fallback' => array('name'=>$ini['Output']['fallback'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'toll_free' =>array('name'=>$ini['Output']['toll_free'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'special' => array('name'=>$ini['Output']['special'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'vodacom' =>array('name'=>$ini['Output']['vodacom'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'mtn' => array('name'=>$ini['Output']['mtn'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'cellc' =>array('name'=>$ini['Output']['cellc'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0), 'incoming' => array('name'=>$ini['Output']['incoming'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0) ); if(!$tagging_enabled) { $grand_total['shared'] = array('name'=>$ini['Output']['shared'],'total_calls'=>0,'total_sec'=>0,'total_cost'=>0); } //make sure that the total row is the last in the set $grand_total['total'] = array('name'=>"Grand Totals",'total_calls'=>0,'total_sec'=>0,'total_cost'=>0); if (!isset($args['groupSelect'])||empty($args['groupSelect'])) { //{{{ find name and extensions of departments(groups) $dep_query = "SELECT group_define_name, extensions FROM liveuser_groups WHERE extensions <> '' AND group_define_name <> ''"; $dep_data = $db->getAll($dep_query); if(handleError($dep_data)) { } //}}} } else { //we have already done all the work in the groupSelect area, no point doing it again $dep_data = array(array('group_define_name'=>$ext_range, 'extensions'=>$extensions)); } //print_r($dep_data); foreach($dep_data as $dep_row) { $dep_string = $dep_row['group_define_name']; //get rid of possible quotes $extensions = trim($dep_row['extensions'],"'"); //echo "NAME: $dep_string EXT LIST: $extensions
"; $summary = fetchSummary($extensions,$src_field,$db,$ini,$grand_total,$dateFrom,$dateTo); //print_r($summary); if($separate_extensions && !empty($summary['total']['total_calls'])) { // Sub heading data $subdata=array($dep_string); //add a new page $page = newPDFPage($pdf,$style,$top,$row_num,$page_num,$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT); displaySummary($summary,$page,$top,$font,$boldfont,$VAT); } } //{{{ now do final page with totals on it $subdata = array('Grand Totals'); $subcols = array(); $page = newPDFPage($pdf,$style,$top,$row_num,$page_num,$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT); displaySummary($grand_total,$page,$top,$font,$boldfont,$VAT); //}}} //{{{ send pdf $pdf_string = $pdf->render(); //send headers $filename.= '.pdf'; header('Content-type: application/pdf'); header('Content-Length: ' . strlen($pdf_string)); header('Content-Disposition: attachment; filename="' . $filename . '"'); echo $pdf_string; die(); //}}} //}}} break; case '10': //Channel Statistics $filename='Channel Statistics '.date("Ymd"); $pdf = true; if(isset($args['chkShowVAT'])&&!empty($args['chkShowVAT'])) { $VAT = $ini['System']['vat_multiplier']; } else { $VAT = false; } //we do not want to execute a query $query = ''; //column layout $coldata = array(''); $result_data=array(''); $cols=array(); if($pdf&&$separate_extensions) { $subtitle=true; $print_summary=true; $subcols=array(50, 400); $print_totals = true; $totalcols=array(320,75,75); } else { //get rid of notices for lack of separate extensions $subcols = ''; $subdata = ''; } //{{{ pdf styling options // Report Heading $hdrdata=array( 'heading' => 'Channel Statistics Report', 'title' => 'Extension Range', 'title_val' => $ext_range, 'target' => 'Outgoing'); //}}} //common PDF initialisation $font = Zend_Pdf_font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA); $boldfont = Zend_Pdf_font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA_BOLD); //{{{ setup pdf document - code courtesy of Sean Preston $pdf = new Zend_Pdf(); // Reverse the page adding order $pdf->pages = array_reverse($pdf->pages); $page = ''; // Setup the page style $style = new Zend_Pdf_Style(); $style->setFont($font, FONTSIZE); $page_num = 0; $row_num = 0; $ext_page_num = 0; $grand_total = array('total'=>array('name'=>'Totals','total_calls'=>0,'total_cost'=>0,'total_sec'=>0)); //{{{ modify date values for printing $showDateFrom = explode(' ',$dateFrom); $showDateFrom = $showDateFrom[0]; $hdrdata['fromDate'] = $showDateFrom; $showDateTo = explode(' ',$dateTo); $showDateTo = $showDateTo[0]; $hdrdata['toDate'] = $showDateTo; //}}} foreach($extension_array as $ext) { //get rid of quotes $ext = trim($ext,"'"); $summary = fetchChannelSummary($db,$grand_total,$dateFrom,$dateTo,$ext); $summary[] = array_shift($summary); //move the totals column to the end if($separate_extensions && !empty($summary['total']['total_calls'])) { //find name(alias) of new extension $name_query="SELECT user_alias FROM liveuser_users WHERE user_phone = '$ext'"; $name_res = $db->query($name_query); if(handleError($name_res)) { if($name_res->numRows()>0) { $name_res->fetchInto($name_row); if(!empty($name_row['user_alias'])) { $old_name = $name_row['user_alias']; } else { $old_name = ''; } } else { $old_name = ''; } } //find name of department(group) that the extension belongs to $dep_query = "SELECT group_define_name FROM liveuser_groups WHERE extensions LIKE '%"."$ext"."%'"; $dep_data = $db->getAll($dep_query); if(handleError($dep_data)) { if(!empty($dep_data)) { $dep_string=''; foreach($dep_data as $dep_row) { if(strlen($dep_string)+strlen($dep_row['group_define_name'])<100) { $dep_string .= $dep_row['group_define_name'].', '; } } //remove last comma $dep_string=substr($dep_string,0,-2); } else { $dep_string = ''; } } // Sub heading data $subdata=array($ext, $old_name, $dep_string); //add a new page $page = newPDFPage($pdf,$style,$top,$row_num,$page_num,$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT); displaySummary($summary,$page,$top,$font,$boldfont,$VAT); } } //{{{ now do final page with totals on it $subdata = array('Grand Totals'); $subcols = array(); $page = newPDFPage($pdf,$style,$top,$row_num,$page_num,$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT); $grand_total[] = array_shift($grand_total); //move the totals column to the end displaySummary($grand_total,$page,$top,$font,$boldfont,$VAT); //}}} //{{{ send pdf $pdf_string = $pdf->render(); //send headers $filename.= '.pdf'; header('Content-type: application/pdf'); header('Content-Length: ' . strlen($pdf_string)); header('Content-Disposition: attachment; filename="' . $filename . '"'); echo $pdf_string; die(); //}}} //}}} break; } //{{{ perform sql query if(''!=$query) { if($query_debug) { echo $query; } $result = $db->query($query); //print_r($result); if(handleError($result)) { if(!$csv&&!$pdf) { $total_billsec = 0; $total_cost = 0; $rows = array(); while($result->fetchInto($res_row)) { if(isset($res_row['src'])) { //multiply cost by amount set for a user //this has to be done here before the number gets changed to the name if(isset($extension_costs_array[$res_row['src']])) { $res_row['cost'] = floatval($res_row['cost']) * floatval($extension_costs_array[$res_row['src']]); } $res_row['src'] = checkNumber($phone_list,$phone_book,$res_row['src']); } if(isset($res_row['dst'])) { $res_row['dst'] = checkNumber($phone_list,$phone_book,$res_row['dst']); } if(isset($res_row['cost'])) { if(isset($args['chkCellDiscount'])&&!empty($args['chkCellDiscount'])) { if(checkIfCell($res_row['dst'])) { $res_row['cost'] = $res_row['cost'] * $ini['System']['cellphone_discount']; } } if(isset($args['chkShowVAT'])&&!empty($args['chkShowVAT'])) { $res_row['cost'] = $res_row['cost'] * $ini['System']['vat_multiplier']; $tpl->assign('vat_inclusive','true'); } } if($print_totals) { if(isset($res_row['billsec'])) { $total_billsec += $res_row['billsec']; } if(isset($res_row['cost'])&&($res_row['cost']>0)) { $total_cost += $res_row['cost']; } if(isset($res_row['total_billsec'])) { $total_billsec += $res_row['total_billsec']; } if(isset($res_row['total_cost'])) { if(isset($args['chkShowVAT'])&&!empty($args['chkShowVAT'])) { $res_row['total_cost'] = $res_row['total_cost'] * $ini['System']['vat_multiplier']; $tpl->assign('vat_inclusive','true'); } $total_cost += $res_row['total_cost']; } } $rows[] = $res_row; } if($print_totals) { $tpl->assign('showTotals','true'); $tpl->assign('total_billsec',$total_billsec); $tpl->assign('total_cost',$total_cost); } $tpl->assign('result',$rows); //{{{ assign options to tpl to allow for easy re-generation of report $tpl->assign("action",$args['action']); $tpl->assign("targetSelect",$args['targetSelect']); $tpl->assign("typeSelect",$args['typeSelect']); $tpl->assign("groupSelect",$args['groupSelect']); $tpl->assign("extList",$args['extList']); $tpl->assign("maxEntries",$args['maxEntries']); $tpl->assign("perPage",$args['perPage']); $tpl->assign("chkShowVAT",$args['chkShowVAT']); $tpl->assign("contactSelect",$args['contactSelect']); $tpl->assign("dateFrom",$dateFrom); $tpl->assign("dateTo",$dateTo); //}}} } else { if($csv) { $total_billsec = 0; $total_cost = 0; $filename.= '.csv'; //do csv export header('Content-type: application/vnd.ms-excel'); header('Content-Disposition: attachment; filename="' . $filename . '"'); //echo("Date,Source,Destination,Billed Time(sec),Cost\r\n"); $hdr = implode(',',$coldata) ."\r\n"; echo $hdr; while($result->fetchInto($res_row)) { $line = ''; //$line = $res_row['calldate'].','.$res_row['src'].','.$res_row['dst'].','.$res_row['billsec'].','; foreach($result_data as $result_column) { switch ($result_column) { case 'cost': if(0>$res_row['cost']) { if(!$debug) { $line.="0.000"; } else { $line.=$res_row['cost']; } } else { if(isset($args['chkCellDiscount'])&&!empty($args['chkCellDiscount'])) { if(checkIfCell($res_row['dst'])) { $res_row['cost'] = $res_row['cost'] * $ini['System']['cellphone_discount']; } } if(isset($args['chkShowVAT'])&&!empty($args['chkShowVAT'])) { $res_row['cost'] = $res_row['cost'] * $ini['System']['vat_multiplier']; } //multiply cost by amount set for a user if(isset($extension_costs_array[$res_row['src']])) { $res_row['cost'] = floatval($res_row['cost']) * floatval($extension_costs_array[$res_row['src']]); } $line.=sprintf("%.3f",$res_row['cost']); $total_cost += $res_row['cost']; } break; case 'src': $line .= checkNumber($phone_list,$phone_book,$res_row['src']); break; case 'dst': $line .= checkNumber($phone_list,$phone_book,$res_row['dst']); break; case 'billsec': $line .= createTimeString($res_row['billsec']); $total_billsec += $res_row['billsec']; break; case 'total_billsec': $line .= createTimeString($res_row['total_billsec']); $total_billsec += $res_row['total_billsec']; break; case 'total_cost': if(isset($args['chkShowVAT'])&&!empty($args['chkShowVAT'])) { $res_row['total_cost'] = $res_row['total_cost'] * $ini['System']['vat_multiplier']; } $line.=sprintf("%.3f",$res_row['total_cost']); $total_cost += $res_row['total_cost']; break; case 'accountcode': $line .= $res_row['accountcode']; break; default: $line .= $res_row[$result_column]; break; } $line .= ','; } $line = rtrim($line,","); $line.="\r\n"; echo $line; } if($print_totals) { echo "\r\nTotal Duration,"; echo createTimeString($total_billsec); echo "\r\nTotal Cost,"; echo sprintf("%.3f",$total_cost); if(isset($args['chkShowVAT'])&&!empty($args['chkShowVAT'])) { echo " (incl. VAT)"; } else { echo " (excl. VAT)"; } } die(); } if($pdf) { //common PDF initialisation $font = Zend_Pdf_font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA); $boldfont = Zend_Pdf_font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA_BOLD); //{{{ setup pdf document - code courtesy of Sean Preston $pdf = new Zend_Pdf(); // Reverse the page adding order $pdf->pages = array_reverse($pdf->pages); $page = ''; // Setup the page style $style = new Zend_Pdf_Style(); $style->setFont($font, FONTSIZE); $page_num = 0; //}}} if(isset($args['chkShowVAT'])&&!empty($args['chkShowVAT'])) { $VAT = $ini['System']['vat_multiplier']; } else { $VAT = false; } $ext_page_num = 0; $row_num = 0; $old_ext = ''; $old_name = ''; $subdata = array(''); $row_count = 0; //used to count the number of rows of data when doing separate extensions $call_count = 0; //used to count the number of rows of data when doing separate extensions $total_call_count = 0; //used to count the total number of rows of data $new_page = false; $total_duration = 0; $total_cost = 0; //{{{ grand totals across all separate extensions $grand_total_duration = 0; $grand_total_cost = 0; //}}} //{{{ modify date values for printing $showDateFrom = explode(' ',$dateFrom); $showDateFrom = $showDateFrom[0]; $hdrdata['fromDate'] = $showDateFrom; $showDateTo = explode(' ',$dateTo); $showDateTo = $showDateTo[0]; $hdrdata['toDate'] = $showDateTo; //}}} if(0<$result->numRows()) { while($result->fetchInto($res_row)) { //if($separate_extensions&&((0!=strcmp($res_row['src'],$old_ext))&&(0!=strcmp($res_row['dst'],$old_ext)))) { if($separate_extensions&&(0!=strcmp($res_row[$group_by],$old_ext))) { if($print_totals&&$old_ext!='') { if($top < 68) { $page = newPDFPage($pdf,$style,$top,$row_num,$page_num,$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT); } displayTotals($total_cost,$total_duration,$call_count,$page,$top,$totalcols,$font,$boldfont,$ini['System']['vat_multiplier']); $grand_total_duration+=$total_duration; $grand_total_cost += $total_cost; } if($print_summary&&$old_ext!='') { if($top < 150) { $page = newPDFPage($pdf,$style,$top,$row_num,$page_num,$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT); } $grand_totals = false; $summary = fetchSummary($old_ext,$src_field,$db,$ini,$grand_totals,$dateFrom,$dateTo); displaySummary($summary,$page,$top,$font,$boldfont,$VAT); } //new extension, so print a new page $old_ext = $res_row[$group_by]; $ext_page_num = 0; $new_page = true; $total_duration = 0; $total_cost = 0; $dep_string = ''; $row_count = 0; $call_count = 0; //find name(alias) of new extension if($group_by == 'src'||$group_by == 'dst') { $old_name = checkNumber($phone_list, $phone_book, $old_ext); if($old_name == $old_ext) { $old_name = ''; } //find name of department(group) that the extension belongs to $dep_query = "SELECT group_define_name FROM liveuser_groups WHERE extensions LIKE '%"."$old_ext"."%'"; $dep_data = $db->getAll($dep_query); if(handleError($dep_data)) { if(!empty($dep_data)) { $dep_string=''; foreach($dep_data as $dep_row) { if(strlen($dep_string)+strlen($dep_row['group_define_name'])<100) { $dep_string .= $dep_row['group_define_name'].', '; } } //remove last comma $dep_string=substr($dep_string,0,-2); } else { $dep_string = ''; } } // Sub heading data $subdata=array($old_ext, $old_name, $dep_string); } else { if(!empty($old_ext)) { $subdata = array($old_ext); } else { $subdata = array(''); } $subcols=array(); } /* $name_query="SELECT user_alias FROM liveuser_users WHERE user_phone = '$old_ext'"; $name_res = $db->query($name_query); if(handleError($name_res)) { if($name_res->numRows()>0) { $name_res->fetchInto($name_row); if(!empty($name_row['user_alias'])) { $old_name = $name_row['user_alias']; } else { $old_name = ''; } } else { $old_name = ''; } } */ } if(0==($row_num%PAGELINES)) { $row_num=0; $new_page = true; } if($new_page) { $new_page = false; $page = newPDFPage($pdf,$style,$top,$row_num,$page_num,$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT); } if(!empty($limit)) { if($row_count<$limit) { $print_row = true; } else { $print_row = false; } } else { $print_row = true; } if($print_row) { if(isset($res_row['billsec'])) { $total_duration+=$res_row['billsec']; } if(isset($res_row['cost'])) { if($res_row['cost']>0) { if(isset($args['chkCellDiscount'])&&!empty($args['chkCellDiscount'])) { if(checkIfCell($res_row['dst'])) { $res_row['cost'] = $res_row['cost'] * $ini['System']['cellphone_discount']; } } //multiply cost by amount set for a user if(isset($extension_costs_array[$res_row['src']])) { $res_row['cost'] = floatval($res_row['cost']) * floatval($extension_costs_array[$res_row['src']]); } $total_cost+=$res_row['cost']; } else { if(!$debug) { $res_row['cost']=0; } } } //draw line of content //$data=array($res_row['calldate'],$res_row['dst'],$res_row['dest_name'],$res_row['billsec'], sprintf("%.3f",$res_row['cost'])); $data = array(); foreach($result_data as $res) { switch($res) { case 'accountcode': if(!empty($res_row['accountcode'])) { $data[] = $res_row['accountcode']; } else { if(3 == $target) { $data[] = ''; } if(4 == $target) { $data[] = ''; } } break; case 'src': $data[] = checkNumber($phone_list,$phone_book,$res_row['src']); break; case 'dst': $data[] = checkNumber($phone_list,$phone_book,$res_row['dst']); break; case 'cost': if(isset($args['chkShowVAT'])&&!empty($args['chkShowVAT'])) { $res_row['cost'] = $res_row['cost'] * $ini['System']['vat_multiplier']; } $data[]=sprintf("%.3f",$res_row['cost']); break; case 'billsec': $data[] = createTimeString($res_row['billsec']); break; case 'total_billsec': $data[] = createTimeString($res_row['total_billsec']); $total_duration += $res_row['total_billsec']; break; case 'total_cost': $data[] = sprintf("%.3f",$res_row['total_cost']); $total_cost += $res_row['total_cost']; break; case 'dst_count': $data[] = $res_row['dst_count']; $call_count+= $res_row['dst_count'] - 1; $total_call_count+= $res_row['dst_count'] -1 ; break; default: $data[]=$res_row[$res]; } } DrawColumn($cols, $data,$page,$top,$font,$boldfont); $top=$top-(FONTSIZE+LINESPACE); $row_num++; $row_count++; $call_count++; $total_call_count++; } else { //do nothing because we can't display anything past the limit //I had to do this because MySQL cannot do limits inside subqueries... } } //print out totals for last extension if($separate_extensions&&$print_totals&&isset($page)) { if($top < 68) { //we need to get a new page for the totals $page = newPDFPage($pdf,$style,$top,$row_num,$page_num,$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT); } displayTotals($total_cost,$total_duration,$call_count,$page,$top,$totalcols,$font,$boldfont,$ini['System']['vat_multiplier']); $grand_total_duration+=$total_duration; $grand_total_cost += $total_cost; } if($separate_extensions&&$print_summary&&isset($page)) { if($top < 150) { $page = newPDFPage($pdf,$style,$top,$row_num,$page_num,$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT); } $grand_totals = false; $summary = fetchSummary($old_ext,$src_field,$db,$ini,$grand_totals,$dateFrom,$dateTo); displaySummary($summary,$page,$top,$font,$boldfont,$VAT); } if($separate_extensions&&$print_totals) { //create last grand Total page $row_count = 0; $subdata=array('Grand Total'); $coldata=array(); $page = newPDFPage($pdf,$style,$top,$row_num,$page_num,$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT); displayTotals($grand_total_cost,$grand_total_duration,$total_call_count,$page,$top,$totalcols,$font,$boldfont,$ini['System']['vat_multiplier'],true); } if(!$separate_extensions&&$print_totals&&isset($page)) { if($top < 68) { //we need to get a new page for the totals $page = newPDFPage($pdf,$style,$top,$row_num,$page_num,$ext_page_num,$hdrdata,$subtitle,$subdata,$subcols,$coldata,$cols,$font,$boldfont,$VAT); } displayTotals($total_cost,$total_duration,$call_count,$page,$top,$totalcols,$font,$boldfont,$ini['System']['vat_multiplier']); } } else { //we do not have any data for that time period //reset height $top=HEIGHT-(FONTSIZE+LINESPACE); // Add a new page $pdf->pages[] = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4); // Assign the style $page =& $pdf->pages[0]; $page->setStyle($style); // Sub heading data $subdata=array('', '', ''); //print out the header DrawHeader($hdrdata,$page,$top,$font,$boldfont); // Print line between column heading and data $page->drawLine(0, $top, WIDTH, $top); $top=$top-(FONTSIZE+LINESPACE); $no_data = array('No Data Available for specified time period'); $no_cols = array(); DrawColumn($no_cols,$no_data,$page,$top,$font,$boldfont,true); } //$pdf->save('test.pdf'); $pdf_string = $pdf->render(); //send headers //$filename = "Detailed Bill.pdf"; $filename.= '.pdf'; //do csv export header('Content-type: application/pdf'); header('Content-Length: ' . strlen($pdf_string)); header('Content-Disposition: attachment; filename="' . $filename . '"'); echo $pdf_string; die(); } } } else { echo "Error: ".$result->getMessage(); } } //}}} }// end of process_data function //}}} //{{{ further initialisation $tpl->setTPL('reports.tpl.html'); $form = new HTML_QuickForm(); //}}} //print_r($args); if($LU->checkRight(VIEW_REPORTS)) { $tpl->assign('reports','true'); $tpl->assign('show_main','true'); $superscript = ''; $tpl->assign('warning','false'); $call_target = array('2'=>'Outgoing','1'=>'Incoming'); if($ini['System']['pincodes_enabled']!= false) { $call_target['3']='Outgoing[PIN]'; $tpl->assign('warning','1. Warning! These reports will disregard the Outgoing[PIN] option in Call Target'); $superscript = '(1)'; } if($ini['System']['amaflags_enabled']!= false) { $call_target['4']='Outgoing[Cost Centre]'; $tpl->assign('warning','1. Warning! These reports will disregard the Outgoing[Cost Centre] option in Call Target'); $superscript = '(1)'; } //create QF elements $form->addElement('date','dateMonthView','Month: ',array('format'=>"Ym",'maxYear'=>'2001','minYear'=>date("Y"))); $form->addElement('date','dateFrom','Date From: ',array('format'=>"Ymd",'maxYear'=>'2001','minYear'=>date("Y"))); $form->addElement('date','dateTo','Date To: ',array('format'=>"Ymd",'maxYear'=>'2001','minYear'=>date("Y"))); $form->addElement('advcheckbox','csv_export', 'Export to CSV: ','',array(1,0)); $form->addElement('advcheckbox','pdf_export', 'Export to PDF: ','',array(1,0)); $form->addElement('advcheckbox','pdf_extension', 'Group By Extension(PDF Only): ','',array(1,0)); $form->addElement('radio','action','Show Longest Calls','',1); $form->addElement('radio','action','Show Most Expensive Calls','',2); $form->addElement('radio','action','Show Most Dialled Numbers','',3); $form->addElement('radio','action','Show Busy Hours Graph'.$superscript,'',4); $form->addElement('radio','action','Show Contact Report','',7); $form->addElement('submit','submitDate','Submit Date Range'); $form->addElement('submit','submitMonth','Submit Month Only'); $form->addElement('text','maxEntries','Maximum Entries: '); $form->addElement('text','perPage','Entries per Page: '); $form->addElement('advcheckbox','chkShowVAT','Include VAT in call costs','',array('1','0')); $form->addElement('select','targetSelect','Call Target: ',$call_target); $call_type = array('0'=>'Both','1'=>'Internal','2'=>'External'); $form->addElement('select','typeSelect','Call Type: ',$call_type); $contact_type = array('0'=>'All','B'=>'Business','P'=>'Private','O'=>'Other'); $form->addElement('select','contactSelect','Contact Type: ',$contact_type); $form->addRule('action','This is a required value', 'required'); $form->addRule('maxEntries','This is a required value', 'required'); $form->addRule('maxEntries','Please enter a number', 'numeric'); $form->addRule('perPage','Please enter a number', 'numeric'); $form->registerRule('XORCheckbox','callback','exclOR'); $form->addRule('csv_export','Please only select one option','XORCheckbox','pdf_export'); $form->addRule('pdf_export','Please only select one option','XORCheckbox','csv_export'); $defaults = array('dateMonthView'=>array('Y'=>date("Y"),'m'=>date('m'),'d'=>date("d")), 'dateFrom'=>array('Y'=>date("Y"),'m'=>date('m'),'d'=>date("d")), 'dateTo'=>array('Y'=>date("Y"),'m'=>date('m'),'d'=>date("d")), 'maxEntries'=>"0", 'perPage'=>"10" ); $form->setDefaults($defaults); if($LU->checkRight(ADMIN)) { if($ini['System']['pincodes_enabled']!= false) { $form->addElement('radio','action','Show Username(PIN) Report'.$superscript,'',8); } if($ini['System']['amaflags_enabled']!= false) { $form->addElement('radio','action','Show Cost Centre Report'.$superscript,'',11); } if($ini['System']['cellphone_discount']!= false) { $form->addElement('advcheckbox','chkCellDiscount','Include Cellphone Discount','',array('1','0')); $tpl->assign('cell_discount','true'); } $form->addElement('radio','action','Channel Statistics Report - All Phones(PDF Only)'.$superscript,'',10); } if($LU->checkRight(VIEW_ALL_EXT)) { $form->addElement('radio','action','Detailed Call Report - All Phones','',5); $form->addElement('radio','action','Aggregated Detailed Call Report - All Phones','',12); $form->addElement('radio','action','Group Statistics Report - All Phones(PDF Only)'.$superscript,'',6); $form->addElement('radio','action','Departmental Summary Report - All Departments(PDF Only)'.$superscript,'',9); $form->addElement('text','extList','Limit Extensions: '); $groups = $LUA->perm->getGroups(); $ext_group = array('0'=>''); foreach($groups as $group) { if(isset($group['extensions'])&&!empty($group['extensions'])) { $ext_group[$group['group_id']] = $group['group_define_name']; } } $form->addElement('select','groupSelect','Limit Group: ',$ext_group); } else { if($LU->checkRight(GROUP_STATS)) { $form->addElement('radio','action',"Detailed Call Report - Group($group_name) Phones",'',5); $form->addElement('radio','action',"Aggregated Detailed Call Report - Group($group_name) Phones",'',12); $form->addElement('radio','action',"Group Statistics - Group($group_name) Phones(PDF Only)".$superscript,'',6); } else { $form->addElement('radio','action','Detailed Call Report - Personal Phone','',5); $form->addElement('radio','action','Aggregated Detailed Call Report - Personal Phone','',12); $form->addElement('radio','action','Statistics - Personal Phone(PDF Only)','',6); } } } if($form->validate()) { $form->process('process_data',false); } else { } $tpl->display($form); ?>