diff --git a/app/destinations/destination_summary.php b/app/destinations/destination_summary.php new file mode 100644 index 0000000000..1a39b058d2 --- /dev/null +++ b/app/destinations/destination_summary.php @@ -0,0 +1,234 @@ + + Portions created by the Initial Developer are Copyright (C) 2023 + the Initial Developer. All Rights Reserved. + + Contributor(s): + Mark J Crane +*/ + +//includes files + require_once dirname(__DIR__, 2) . "/resources/require.php"; + require_once "resources/check_auth.php"; + //require_once "resources/paging.php"; + +//check permissions + if (permission_exists('destination_view')) { + //access granted + } + else { + echo "access denied"; + exit; + } + +//add multi-lingual support + $language = new text; + $text = $language->get(); + +//retrieve submitted data + if (!empty($_REQUEST)) { + $quick_select = $_REQUEST['quick_select']; + $start_stamp_begin = $_REQUEST['start_stamp_begin']; + $start_stamp_end = $_REQUEST['start_stamp_end']; + $include_internal = $_REQUEST['include_internal']; + } + else { + $quick_select = 3; //set default + } + +//get the summary + $destination = new destinations; + $destination->domain_uuid = $_SESSION['domain_uuid']; + $destination->quick_select = $quick_select; + $destination->start_stamp_begin = $start_stamp_begin ?? null; + $destination->start_stamp_end = $start_stamp_end ?? null; + $destination->include_internal = $include_internal ?? null; + $summary = $destination->destination_summary(); + +//set the http header + if (!empty($_REQUEST['type']) && $_REQUEST['type'] == "csv") { + + //set the headers + header('Content-type: application/octet-binary'); + header('Content-Disposition: attachment; filename=user-summary.csv'); + + //show the column names on the first line + $z = 0; + foreach($summary[1] as $key => $val) { + if ($z == 0) { + echo '"'.$key.'"'; + } + else { + echo ',"'.$key.'"'; + } + $z++; + } + echo "\n"; + + //add the values to the csv + $x = 0; + foreach($summary as $users) { + $z = 0; + foreach($users as $key => $val) { + if ($z == 0) { + echo '"'.$summary[$x][$key].'"'; + } + else { + echo ',"'.$summary[$x][$key].'"'; + } + $z++; + } + echo "\n"; + $x++; + } + exit; + } + +//include the header + $document['title'] = $text['title-destination_summary']; + require_once "resources/header.php"; + +//css grid adjustment + echo "\n"; + +//show the content + echo "
\n"; + echo "
".$text['title-destination_summary']."
\n"; + echo "
\n"; + if (permission_exists('xml_cdr_extension_summary_all') && $_GET['show'] != 'all') { + echo button::create(['type'=>'button','label'=>$text['button-show_all'],'icon'=>$_SESSION['theme']['button_icon_all'],'collapse'=>'hide-sm-dn','link'=>'xml_cdr_extension_summary.php?show=all']); + } + echo button::create(['type'=>'button','label'=>$text['button-download_csv'],'icon'=>$_SESSION['theme']['button_icon_download'],'collapse'=>'hide-sm-dn','link'=>'xml_cdr_extension_summary.php?'.(!empty($_SERVER["QUERY_STRING"]) ? $_SERVER["QUERY_STRING"].'&' : null).'type=csv']); + echo button::create(['type'=>'button','label'=>$text['button-reset'],'icon'=>$_SESSION['theme']['button_icon_reset'],'collapse'=>'hide-xs','style'=>'margin-left: 15px;','link'=>'xml_cdr_extension_summary.php']); + echo button::create(['type'=>'button','label'=>$text['button-update'],'icon'=>$_SESSION['theme']['button_icon_save'],'id'=>'btn_save','collapse'=>'hide-xs','onclick'=>"document.getElementById('frm').submit();"]); + echo "
\n"; + echo "
\n"; + echo "
\n"; + + if (permission_exists('xml_cdr_search')) { + echo "
\n"; + + echo "
\n"; + + echo "
\n"; + echo "
\n"; + echo " ".$text['label-preset']."\n"; + echo "
\n"; + echo "
\n"; + echo " \n"; + echo "
\n"; + echo "
\n"; + + //echo "
\n"; + //echo "
\n"; + //echo " ".$text['label-include_internal']."\n"; + //echo "
\n"; + //echo "
\n"; + //echo " \n"; + //echo "
\n"; + //echo "
\n"; + + echo "
\n"; + echo "
\n"; + echo " ".$text['label-start_date_time']."\n"; + echo "
\n"; + echo "
\n"; + echo " \n"; + echo "
\n"; + echo "
\n"; + + echo "
\n"; + echo "
\n"; + echo " ".$text['label-end_date_time']."\n"; + echo "
\n"; + echo "
\n"; + echo " \n"; + echo "
\n"; + echo "
\n"; + + echo "
\n"; + + if (!empty($_GET['show']) && $_GET['show'] == 'all' && permission_exists('xml_cdr_extension_summary_all')) { + echo ""; + } + + echo "
"; + } + +//show the results + echo "\n"; + echo " \n"; + if (!empty($_GET['show']) && $_GET['show'] === "all" && permission_exists('xml_cdr_extension_summary_all')) { + echo " \n"; + } + echo " \n"; + if (permission_exists('number_alias')) { + echo " \n"; + } + echo " \n"; + echo " \n"; + echo " \n"; + echo " \n"; + echo " \n"; + echo " \n"; + + if (is_array($summary)) { + foreach ($summary as $key => $row) { + echo "\n"; + if (!empty($_GET['show']) && $_GET['show'] === "all" && permission_exists('xml_cdr_extension_summary_all')) { + echo " \n"; + } + echo " \n"; + if (permission_exists('number_alias')) { + echo " \n"; + } + echo " \n"; + echo " \n"; + echo " \n"; + //echo " \n"; + echo " \n"; + echo " \n"; + echo "\n"; + } + } + + echo "
".$text['label-domain']."".$text['label-destination_number']."".$text['label-number_alias']."".$text['label-answered']."".$text['label-unique_callers']."".$text['label-total_calls']."".$text['label-duration']."".$text['label-description']."
".escape($row['domain_name'])."".escape($row['destination_number'])."".escape($row['number_alias'])." ".escape($row['answered_calls'])." ".escape($row['unique_callers'])." ".escape($row['total_calls'])." ".(($row['outbound_calls'] != '') ? escape($row['outbound_calls']) : "0")." ".(($row['total_seconds'] != '') ? format_hours($row['total_seconds']) : '0:00:00')."".escape($row['destination_description'])." 
\n"; + echo "
\n"; + +//show the footer + require_once "resources/footer.php"; + +?> diff --git a/app/destinations/resources/classes/destinations.php b/app/destinations/resources/classes/destinations.php index 863c4c99ff..5f6dc63186 100644 --- a/app/destinations/resources/classes/destinations.php +++ b/app/destinations/resources/classes/destinations.php @@ -59,6 +59,9 @@ if (!class_exists('destinations')) { $this->domain_uuid = $_SESSION['domain_uuid']; } + //get the email queue settings + $this->setting = new settings(); + //assign private variables $this->app_name = 'destinations'; $this->app_uuid = '5ec89622-b19c-3559-64f0-afde802ab139'; @@ -1105,6 +1108,150 @@ if (!class_exists('destinations')) { } } //method + + /** + * destination summary returns an array + */ + public function destination_summary() { + + //set the time zone + if (!empty($this->setting->get('domain', 'time_zone'))) { + $time_zone = $this->setting->get('domain', 'time_zone'); + } + else { + $time_zone = date_default_timezone_get(); + } + + //build the date range + if ((!empty($this->start_stamp_begin) && strlen($this->start_stamp_begin) > 0) || !empty($this->start_stamp_end)) { + unset($this->quick_select); + if (strlen($this->start_stamp_begin) > 0 && !empty($this->start_stamp_end)) { + $sql_date_range = " and start_stamp between :start_stamp_begin::timestamptz and :start_stamp_end::timestamptz \n"; + $parameters['start_stamp_begin'] = $this->start_stamp_begin.':00.000 '.$time_zone; + $parameters['start_stamp_end'] = $this->start_stamp_end.':59.999 '.$time_zone; + } + else { + if (!empty($this->start_stamp_begin)) { + $sql_date_range = "and start_stamp >= :start_stamp_begin::timestamptz \n"; + $parameters['start_stamp_begin'] = $this->start_stamp_begin.':00.000 '.$time_zone; + } + if (!empty($this->start_stamp_end)) { + $sql_date_range .= "and start_stamp <= :start_stamp_end::timestamptz \n"; + $parameters['start_stamp_end'] = $this->start_stamp_end.':59.999 '.$time_zone; + } + } + } + else { + switch ($this->quick_select) { + case 1: $sql_date_range = "and start_stamp >= '".date('Y-m-d H:i:s.000', strtotime("-1 week"))." ".$time_zone."'::timestamptz \n"; break; //last 7 days + case 2: $sql_date_range = "and start_stamp >= '".date('Y-m-d H:i:s.000', strtotime("-1 hour"))." ".$time_zone."'::timestamptz \n"; break; //last hour + case 3: $sql_date_range = "and start_stamp >= '".date('Y-m-d')." "."00:00:00.000 ".$time_zone."'::timestamptz \n"; break; //today + case 4: $sql_date_range = "and start_stamp between '".date('Y-m-d',strtotime("-1 day"))." "."00:00:00.000 ".$time_zone."'::timestamptz and '".date('Y-m-d',strtotime("-1 day"))." "."23:59:59.999 ".$time_zone."'::timestamptz \n"; break; //yesterday + case 5: $sql_date_range = "and start_stamp >= '".date('Y-m-d',strtotime("this week"))." "."00:00:00.000 ".$time_zone."' \n"; break; //this week + case 6: $sql_date_range = "and start_stamp >= '".date('Y-m-')."01 "."00:00:00.000 ".$time_zone."'::timestamptz \n"; break; //this month + case 7: $sql_date_range = "and start_stamp >= '".date('Y-')."01-01 "."00:00:00.000 ".$time_zone."'::timestamptz \n"; break; //this year + } + } + + //calculate the summary data + $sql = "select \n"; + $sql .= "d.domain_uuid, \n"; + $sql .= "n.domain_name, \n"; + $sql .= "d.destination_uuid, \n"; + $sql .= "d.dialplan_uuid, \n"; + $sql .= "d.destination_type, \n"; + $sql .= "d.destination_prefix, \n"; + $sql .= "d.destination_number, \n"; + + //total_calls + $sql .= "count(*) \n"; + $sql .= "filter ( \n"; + $sql .= " where caller_destination in (d.destination_number, concat(d.destination_prefix, d.destination_number), concat('+', d.destination_prefix, d.destination_number)) \n"; + $sql .= ") \n"; + $sql .= "as total_calls, \n"; + + //answered_calls + $sql .= "count(*) \n"; + $sql .= "filter ( \n"; + $sql .= " where caller_destination in (d.destination_number, concat(d.destination_prefix, d.destination_number), concat('+', d.destination_prefix, d.destination_number)) \n"; + $sql .= " and billsec > 0 \n"; + $sql .= ") \n"; + $sql .= "as answered_calls, \n"; + + //unique_callers + $sql .= "count(distinct(c.caller_id_name)) \n"; + $sql .= "filter ( \n"; + $sql .= " where caller_destination in (d.destination_number, concat(d.destination_prefix, d.destination_number), concat('+', d.destination_prefix, d.destination_number)) \n"; + $sql .= " and billsec > 0 \n"; + $sql .= ") \n"; + $sql .= "as unique_callers, \n"; + + //total_seconds + $sql .= "sum(billsec) \n"; + $sql .= "filter ( \n"; + $sql .= " where caller_destination in (d.destination_number, concat(d.destination_prefix, d.destination_number), concat('+', d.destination_prefix, d.destination_number)) \n"; + $sql .= " and billsec > 0 \n"; + $sql .= ") \n"; + $sql .= "as total_seconds, \n"; + + $sql .= "d.destination_description \n"; + + $sql .= "from v_destinations as d, v_domains as n, \n"; + $sql .= "( select \n"; + $sql .= " domain_uuid, \n"; + $sql .= " extension_uuid, \n"; + $sql .= " caller_id_name, \n"; + $sql .= " caller_id_number, \n"; + $sql .= " caller_destination, \n"; + $sql .= " destination_number, \n"; + $sql .= " missed_call, \n"; + $sql .= " answer_stamp, \n"; + $sql .= " bridge_uuid, \n"; + $sql .= " direction, \n"; + $sql .= " start_stamp, \n"; + $sql .= " hangup_cause, \n"; + $sql .= " originating_leg_uuid, \n"; + $sql .= " billsec, \n"; + $sql .= " cc_side, \n"; + $sql .= " sip_hangup_disposition \n"; + $sql .= " from v_xml_cdr \n"; + if (!(!empty($_GET['show']) && $_GET['show'] === 'all' && permission_exists('destination_summary_all'))) { + $sql .= " where domain_uuid = :domain_uuid \n"; + } + else { + $sql .= " where true \n"; + } + $sql .= " and direction = 'inbound' \n"; + $sql .= " and caller_destination is not null \n"; + $sql .= $sql_date_range; + $sql .= ") as c \n"; + + $sql .= "where \n"; + $sql .= "d.domain_uuid = n.domain_uuid \n"; + if (!(!empty($_GET['show']) && $_GET['show'] === 'all' && permission_exists('destination_summary_all'))) { + $sql .= "and d.domain_uuid = :domain_uuid \n"; + } + $sql .= "and destination_type = 'inbound' \n"; + $sql .= "and destination_enabled = 'true' \n"; + $sql .= "group by d.domain_uuid, d.destination_uuid, d.dialplan_uuid, n.domain_name, d.destination_type, d.destination_prefix, d.destination_number \n"; + $sql .= "order by destination_number asc \n"; + if (!(!empty($_GET['show']) && $_GET['show'] === 'all' && permission_exists('destination_summary_all'))) { + $parameters['domain_uuid'] = $this->domain_uuid; + } + + $database = new database; + $summary = $database->select($sql, $parameters, 'all'); + unset($parameters); + + //if (!empty($this->start_stamp_begin) && !empty($this->start_stamp_end)) { + // view_array($summary); + //} + + //return the array + return $summary; + } + + /** * define singular function to convert a word in english to singular */