diff --git a/app/scripts/resources/scripts/app/voicemail/resources/functions/record_message.lua b/app/scripts/resources/scripts/app/voicemail/resources/functions/record_message.lua index a459da7b8a..93a61d9c68 100644 --- a/app/scripts/resources/scripts/app/voicemail/resources/functions/record_message.lua +++ b/app/scripts/resources/scripts/app/voicemail/resources/functions/record_message.lua @@ -587,7 +587,7 @@ --if the recording is below the minimal length then re-record the message if (message_length > 2) then - --continue + session:setVariable("voicemail_message_seconds", message_length); else if (session:ready()) then --your recording is below the minimal acceptable length, please try again diff --git a/app/xml_cdr/app_config.php b/app/xml_cdr/app_config.php index b130e477ef..3cd481481d 100644 --- a/app/xml_cdr/app_config.php +++ b/app/xml_cdr/app_config.php @@ -197,6 +197,9 @@ $apps[$x]['permissions'][$y]['name'] = "xml_cdr_lose_race"; $apps[$x]['permissions'][$y]['groups'][] = "superadmin"; $y++; + $apps[$x]['permissions'][$y]['name'] = "xml_cdr_enterprise_leg"; + $apps[$x]['permissions'][$y]['groups'][] = "superadmin"; + $y++; $apps[$x]['permissions'][$y]['name'] = "xml_cdr_cc_agent_leg"; $apps[$x]['permissions'][$y]['groups'][] = "superadmin"; $y++; @@ -537,6 +540,12 @@ $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(1)"; $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "The leg of the call a or b."; $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = "originating_leg_uuid"; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "uuid"; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text"; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "char(36)"; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "Originating Leg UUID. Used to identify legs of an enterprise ring group - and exclude them "; + $z++; $apps[$x]['db'][$y]['fields'][$z]['name'] = "pdd_ms"; $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "numeric"; $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "numeric"; @@ -555,6 +564,12 @@ $apps[$x]['db'][$y]['fields'][$z]['type'] = "text"; $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "Save the last application data."; $z++; + $apps[$x]['db'][$y]['fields'][$z]['name'] = "voicemail_message"; + $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "boolean"; + $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text"; + $apps[$x]['db'][$y]['fields'][$z]['type']['mysql'] = "text"; + $apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = ""; + $z++; $apps[$x]['db'][$y]['fields'][$z]['name'] = "missed_call"; $apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "boolean"; $apps[$x]['db'][$y]['fields'][$z]['type']['sqlite'] = "text"; diff --git a/app/xml_cdr/resources/classes/xml_cdr.php b/app/xml_cdr/resources/classes/xml_cdr.php index 904f920290..4f488c1002 100644 --- a/app/xml_cdr/resources/classes/xml_cdr.php +++ b/app/xml_cdr/resources/classes/xml_cdr.php @@ -145,10 +145,12 @@ if (!class_exists('xml_cdr')) { $this->fields[] = "record_path"; $this->fields[] = "record_name"; $this->fields[] = "leg"; + $this->fields[] = "originating_leg_uuid"; $this->fields[] = "pdd_ms"; $this->fields[] = "rtp_audio_in_mos"; $this->fields[] = "last_app"; $this->fields[] = "last_arg"; + $this->fields[] = "voicemail_message"; $this->fields[] = "cc_side"; $this->fields[] = "cc_member_uuid"; $this->fields[] = "cc_queue_joined_epoch"; @@ -316,7 +318,7 @@ if (!class_exists('xml_cdr')) { //set missed calls $missed_call = 'false'; - if (strlen($xml->variables->answer_stamp) == 0) { + if ($xml->variables->cc_side != "agent" && strlen($xml->variables->originating_leg_uuid) == 0 && $xml->variables->call_direction != 'outbound' && strlen($xml->variables->answer_stamp) == 0) { $missed_call = 'true'; } if ($xml->variables->missed_call == 'true') { @@ -390,6 +392,14 @@ if (!class_exists('xml_cdr')) { $this->array[$key]['last_app'] = urldecode($xml->variables->last_app); $this->array[$key]['last_arg'] = urldecode($xml->variables->last_arg); + //voicemail message success + if ($xml->variables->voicemail_action == "save" && $xml->variables->voicemail_message_seconds > 0){ + $this->array[$key]['voicemail_message'] = "true"; + } + else { //if ($xml->variables->voicemail_action == "save") { + $this->array[$key]['voicemail_message'] = "false"; + } + //conference $this->array[$key]['conference_name'] = urldecode($xml->variables->conference_name); $this->array[$key]['conference_uuid'] = urldecode($xml->variables->conference_uuid); @@ -404,6 +414,9 @@ if (!class_exists('xml_cdr')) { //store the call leg $this->array[$key]['leg'] = $leg; + //store the originating leg uuid + $this->array[$key]['originating_leg_uuid'] = urldecode($xml->variables->originating_leg_uuid); + //store post dial delay, in milliseconds $this->array[$key]['pdd_ms'] = urldecode($xml->variables->progress_mediamsec) + urldecode($xml->variables->progressmsec); @@ -430,7 +443,7 @@ if (!class_exists('xml_cdr')) { if (strlen($domain_name) == 0) { $presence_id = urldecode($xml->variables->presence_id); if (strlen($presence_id) > 0) { - $presence_array = explode($presence_id); + $presence_array = explode($presence_id, '%40'); $domain_name = $presence_array[1]; } } @@ -918,13 +931,13 @@ if (!class_exists('xml_cdr')) { if (strlen($this->start_stamp_begin) > 0 || strlen($this->start_stamp_end) > 0) { unset($this->quick_select); if (strlen($this->start_stamp_begin) > 0 && strlen($this->start_stamp_end) > 0) { - $sql_date_range .= " and start_stamp between :start_stamp_begin and :start_stamp_end \n"; + $sql_date_range = " and start_stamp between :start_stamp_begin and :start_stamp_end \n"; $parameters['start_stamp_begin'] = $this->start_stamp_begin.':00.000'; $parameters['start_stamp_end'] = $this->start_stamp_end.':59.999'; } else { if (strlen($this->start_stamp_begin) > 0) { - $sql_date_range .= "and start_stamp >= :start_stamp_begin \n"; + $sql_date_range = "and start_stamp >= :start_stamp_begin \n"; $parameters['start_stamp_begin'] = $this->start_stamp_begin.':00.000'; } if (strlen($this->start_stamp_end) > 0) { @@ -935,13 +948,13 @@ if (!class_exists('xml_cdr')) { } else { switch ($this->quick_select) { - case 1: $sql_date_range .= "and start_stamp >= '".date('Y-m-d H:i:s.000', strtotime("-1 week"))."' \n"; break; //last 7 days - case 2: $sql_date_range .= "and start_stamp >= '".date('Y-m-d H:i:s.000', strtotime("-1 hour"))."' \n"; break; //last hour - case 3: $sql_date_range .= "and start_stamp >= '".date('Y-m-d')." "."00:00:00.000' \n"; break; //today - case 4: $sql_date_range .= "and start_stamp between '".date('Y-m-d',strtotime("-1 day"))." "."00:00:00.000' and '".date('Y-m-d',strtotime("-1 day"))." "."23:59:59.999' \n"; break; //yesterday - case 5: $sql_date_range .= "and start_stamp >= '".date('Y-m-d',strtotime("this week"))." "."00:00:00.000' \n"; break; //this week - case 6: $sql_date_range .= "and start_stamp >= '".date('Y-m-')."01 "."00:00:00.000' \n"; break; //this month - case 7: $sql_date_range .= "and start_stamp >= '".date('Y-')."01-01 "."00:00:00.000' \n"; break; //this year + case 1: $sql_date_range = "and start_stamp >= '".date('Y-m-d H:i:s.000', strtotime("-1 week"))."' \n"; break; //last 7 days + case 2: $sql_date_range = "and start_stamp >= '".date('Y-m-d H:i:s.000', strtotime("-1 hour"))."' \n"; break; //last hour + case 3: $sql_date_range = "and start_stamp >= '".date('Y-m-d')." "."00:00:00.000' \n"; break; //today + case 4: $sql_date_range = "and start_stamp between '".date('Y-m-d',strtotime("-1 day"))." "."00:00:00.000' and '".date('Y-m-d',strtotime("-1 day"))." "."23:59:59.999' \n"; break; //yesterday + case 5: $sql_date_range = "and start_stamp >= '".date('Y-m-d',strtotime("this week"))." "."00:00:00.000' \n"; break; //this week + case 6: $sql_date_range = "and start_stamp >= '".date('Y-m-')."01 "."00:00:00.000' \n"; break; //this month + case 7: $sql_date_range = "and start_stamp >= '".date('Y-')."01-01 "."00:00:00.000' \n"; break; //this year } } @@ -969,7 +982,10 @@ if (!class_exists('xml_cdr')) { $sql .= "filter ( \n"; $sql .= " where c.extension_uuid = e.extension_uuid \n"; $sql .= " and missed_call = true \n"; - if (!permission_exists('xml_cdr_lose_race')) { + if (!permission_exists('xml_cdr_enterprise_leg')) { + $sql .= " and originating_leg_uuid is null \n"; + } + elseif (!permission_exists('xml_cdr_lose_race')) { $sql .= " and hangup_cause <> 'LOSE_RACE' \n"; } if ($this->include_internal) { @@ -1025,7 +1041,10 @@ if (!class_exists('xml_cdr')) { $sql .= "count(*) \n"; $sql .= "filter ( \n"; $sql .= " where c.extension_uuid = e.extension_uuid \n"; - if (!permission_exists('xml_cdr_lose_race')) { + if (!permission_exists('xml_cdr_enterprise_leg')) { + $sql .= " and originating_leg_uuid is null \n"; + } + elseif (!permission_exists('xml_cdr_lose_race')) { $sql .= " and hangup_cause <> 'LOSE_RACE' \n"; } if ($this->include_internal) { @@ -1076,6 +1095,7 @@ if (!class_exists('xml_cdr')) { $sql .= " direction, \n"; $sql .= " start_stamp, \n"; $sql .= " hangup_cause, \n"; + $sql .= " originating_leg_uuid, \n"; $sql .= " billsec \n"; $sql .= " from v_xml_cdr \n"; if (!($_GET['show'] === 'all' && permission_exists('xml_cdr_all'))) { @@ -1210,7 +1230,7 @@ if (!class_exists('xml_cdr')) { // If the range starts with an '-' we start from the beginning // If not, we forward the file pointer // And make sure to get the end byte if spesified - if ($range0 == '-') { + if ($range == '-') { // The n-number of the last bytes is requested $c_start = $size - substr($range, 1); } diff --git a/app/xml_cdr/v_xml_cdr_import.php b/app/xml_cdr/v_xml_cdr_import.php index d8a3198aef..6230f8c030 100644 --- a/app/xml_cdr/v_xml_cdr_import.php +++ b/app/xml_cdr/v_xml_cdr_import.php @@ -198,6 +198,14 @@ $database->fields['last_app'] = urldecode($xml->variables->last_app); $database->fields['last_arg'] = urldecode($xml->variables->last_arg); + //voicemail message success + if ($xml->variables->voicemail_action == "save" && $xml->variables->voicemail_message_seconds > 0){ + $database->fields['voicemail_message'] = "true"; + } + elseif ($xml->variables->voicemail_action == "save") { + $database->fields['voicemail_message'] = "false"; + } + //conference $database->fields['conference_name'] = urldecode($xml->variables->conference_name); $database->fields['conference_uuid'] = urldecode($xml->variables->conference_uuid); @@ -211,7 +219,7 @@ //set missed calls $database->fields['missed_call'] = 'false'; - if (strlen($xml->variables->answer_stamp) == 0) { + if ($xml->variables->cc_side != "agent" && strlen($xml->variables->originating_leg_uuid) == 0 && $xml->variables->call_direction != 'outbound' && strlen($xml->variables->answer_stamp) == 0) { $database->fields['missed_call'] = 'true'; } if ($xml->variables->missed_call == 'true') { @@ -292,7 +300,7 @@ if (strlen($domain_name) == 0) { $presence_id = urldecode($xml->variables->presence_id); if (strlen($presence_id) > 0) { - $presence_array = explode($presence_id); + $presence_array = explode($presence_id, '%40'); $domain_name = $presence_array[1]; } } diff --git a/app/xml_cdr/xml_cdr.php b/app/xml_cdr/xml_cdr.php index 5cd4e71c94..05d889091b 100644 --- a/app/xml_cdr/xml_cdr.php +++ b/app/xml_cdr/xml_cdr.php @@ -796,7 +796,7 @@ } //tta (time to answer) if (permission_exists('xml_cdr_tta')) { - $content .= " ".(($row['tta'] > 0) ? $row['tta']."s" : " ")."\n"; + $content .= " ".(($row['tta'] >= 0) ? $row['tta']."s" : " ")."\n"; } //duration if (permission_exists('xml_cdr_duration')) { @@ -823,14 +823,6 @@ } $content .= "\n"; - - if (!permission_exists('xml_cdr_lose_race') && $row['hangup_cause'] == 'LOSE_RACE') { - $content = ''; - } - //show agent originated legs only to those with the permission - if (!permission_exists('xml_cdr_cc_agent_leg') && $row['cc_side'] == "agent") { - $content = ''; - } //show the leg b only to those with the permission if ($row['leg'] == 'a') { echo $content; diff --git a/app/xml_cdr/xml_cdr_export.php b/app/xml_cdr/xml_cdr_export.php index b39ce53d03..96a12d26f7 100644 --- a/app/xml_cdr/xml_cdr_export.php +++ b/app/xml_cdr/xml_cdr_export.php @@ -192,7 +192,7 @@ $data_body[$p] .= ''.format_phone($fields['destination_number']).''; $data_body[$p] .= ''.$fields['start_stamp'].''; $total['tta'] += ($fields['tta'] > 0) ? $fields['tta'] : 0; - $data_body[$p] .= ''.(($fields['tta'] > 0) ? $fields['tta'].'s' : null).''; + $data_body[$p] .= ''.(($fields['tta'] >= 0) ? $fields['tta'].'s' : null).''; $seconds = ($fields['hangup_cause'] == "ORIGINATOR_CANCEL") ? $fields['duration'] : round(($fields['billmsec'] / 1000), 0, PHP_ROUND_HALF_UP); $total['duration'] += $seconds; $data_body[$p] .= ''.gmdate("G:i:s", $seconds).''; diff --git a/app/xml_cdr/xml_cdr_inc.php b/app/xml_cdr/xml_cdr_inc.php index df1653fbb1..d7255167d8 100644 --- a/app/xml_cdr/xml_cdr_inc.php +++ b/app/xml_cdr/xml_cdr_inc.php @@ -417,6 +417,13 @@ $sql .= "and hangup_cause like :hangup_cause "; $parameters['hangup_cause'] = '%'.$hangup_cause.'%'; } + elseif (!permission_exists('xml_cdr_lose_race') && !permission_exists('xml_cdr_enterprise_leg')) { + $sql .= "and hangup_cause != 'LOSE_RACE' "; + } + //exclude enterprise ring group legs + if (!permission_exists('xml_cdr_enterprise_leg')) { + $sql .= "and originating_leg_uuid IS NULL "; + } if (strlen($call_result) > 0) { switch ($call_result) { case 'answered': @@ -430,10 +437,20 @@ break; case 'cancelled': if ($direction == 'inbound' || $direction == 'local' || $call_result == 'missed') { - $sql = "and (answer_stamp is null and bridge_uuid is null and sip_hangup_disposition <> 'send_refuse') "; + $sql .= " + and (( + answer_stamp is null + and bridge_uuid is null + and sip_hangup_disposition <> 'send_refuse' + ) + or ( + answer_stamp is not null + and bridge_uuid is null + and voicemail_message = false + ))"; } else if ($direction == 'outbound') { - $sql = "and (answer_stamp is null and bridge_uuid is not null) "; + $sql .= "and (answer_stamp is null and bridge_uuid is not null) "; } else { $sql .= " @@ -447,10 +464,17 @@ direction = 'outbound' and answer_stamp is null and bridge_uuid is not null + ) + or ( + (direction = 'inbound' or direction = 'local') + and answer_stamp is not null + and bridge_uuid is null + and voicemail_message = false ))"; } break; - default: //failed + default: + $sql .= "and (answer_stamp is null and bridge_uuid is null and duration = 0) "; //$sql .= "and (answer_stamp is null and bridge_uuid is null and billsec = 0 and sip_hangup_disposition = 'send_refuse') "; } } @@ -507,6 +531,10 @@ $sql .= "and (c.record_path is null or c.record_name is null) "; } } + //show agent originated legs only to those with the permission + if (!permission_exists('xml_cdr_cc_agent_leg')) { + $sql .= "and (cc_side is null or cc_side != 'agent') "; + } //end where if (strlen($order_by) > 0) { $sql .= order_by($order_by, $order); diff --git a/app/xml_cdr/xml_cdr_statistics_inc.php b/app/xml_cdr/xml_cdr_statistics_inc.php index 574440d413..e695b8e67c 100644 --- a/app/xml_cdr/xml_cdr_statistics_inc.php +++ b/app/xml_cdr/xml_cdr_statistics_inc.php @@ -153,7 +153,7 @@ $parameters['domain_uuid'] = $_SESSION['domain_uuid']; } if ($missed == true) { - $sql_where_ands[] = "billsec = '0'"; + $sql_where_ands[] = "missed_call = true "; } if (strlen($start_epoch) > 0 && strlen($stop_epoch) > 0) { $sql_where_ands[] = "start_epoch between :start_epoch and :stop_epoch"; @@ -280,10 +280,15 @@ $sql_where_ands[] = "leg = :leg"; $parameters['leg'] = $leg; } + //Exclude enterprise ring group legs + if (!permission_exists('xml_cdr_enterprise_leg')) { + $sql_where_ands[] .= "originating_leg_uuid IS NULL"; + } //If you can't see lose_race, don't run stats on it - if (!permission_exists('xml_cdr_lose_race')) { + elseif (!permission_exists('xml_cdr_lose_race')) { $sql_where_ands[] = "hangup_cause != 'LOSE_RACE'"; } + //if not admin or superadmin, only show own calls if (!permission_exists('xml_cdr_domain')) { @@ -349,7 +354,7 @@ //get the call volume between a start end end time in seconds function get_call_volume_between($start, $end, $where, $parameters) { - $sql = "select count(*) as count, sum(billsec) as seconds from v_xml_cdr "; + $sql = "select count(*) as count, sum(billsec) as seconds, sum(answer_stamp - start_stamp) as tta from v_xml_cdr "; $sql .= $where." "; $sql .= "start_epoch between :start and :end "; $parameters['start'] = $start; @@ -360,6 +365,7 @@ return array( 'volume' => $row['count'], 'seconds' => $row['seconds'], + 'tta' => $row['tta'], ); } return false; @@ -379,14 +385,13 @@ $stats[$i]['volume'] = $stat_range ? $stat_range['volume'] : 0; $stats[$i]['seconds'] = $stat_range ? $stat_range['seconds'] : 0; $stats[$i]['minutes'] = $stats[$i]['seconds'] / 60; - $stats[$i]['avg_sec'] = $stats[$i]['volume'] == 0 ? 0 : $stats[$i]['seconds'] / $stats[$i]['volume']; if ($missed) { //we select only missed calls at first place - no reasons to select it again $stats[$i]['missed'] = $stats[$i]['volume']; } else { - $where = $sql_where."billsec = '0' and "; + $where = $sql_where."missed_call = true and "; $stat_range = get_call_volume_between($stats[$i]['start_epoch'], $stats[$i]['stop_epoch'], $where, $parameters); $stats[$i]['missed'] = $stat_range ? $stat_range['volume'] : 0; } @@ -403,6 +408,9 @@ //answer / seizure ratio $stats[$i]['asr'] = $stats[$i]['volume'] == 0 ? 0 : ($success_volume / $stats[$i]['volume'] * 100); + //average time to answer + $stats[$i]['avg_tta'] = $stats[$i]['volume'] == 0 ? 0 : round($stat_range['tta'] / $success_volume); + //average length of call $stats[$i]['aloc'] = $success_volume == 0 ? 0 : $stats[$i]['minutes'] / $success_volume; }