diff --git a/agc_2-X/trunk/UPGRADE b/agc_2-X/trunk/UPGRADE
index f786ff1d..cc639a5b 100644
--- a/agc_2-X/trunk/UPGRADE
+++ b/agc_2-X/trunk/UPGRADE
@@ -238,6 +238,10 @@ OTHER CHANGES:
placed from the agent screen, and if one exists it will be deleted
before the manual dial call is placed.
+61. Added ability to transfer customer chats to another chat group or agent
+
+62. Added API Log Report to Admin Utilities page
+
diff --git a/agc_2-X/trunk/docs/CHAT_MESSAGING.txt b/agc_2-X/trunk/docs/CHAT_MESSAGING.txt
index 25ca1c06..a5d8cfa4 100644
--- a/agc_2-X/trunk/docs/CHAT_MESSAGING.txt
+++ b/agc_2-X/trunk/docs/CHAT_MESSAGING.txt
@@ -1,4 +1,4 @@
-CHAT MESSAGING Started 2014-05-01 Updated 2016-01-20
+CHAT MESSAGING Started 2014-05-01 Updated 2016-03-05
After over 18 months of development, the Chat Messaging system for Vicidial was added to svn/trunk on December 13th, 2015(svn revision 2428). Our Chat messaging allows for customers to chat with agents from websites, as well as allowing managers to chat with agents and agents to chat with other agents all within their existing agent screen.
@@ -8,6 +8,8 @@ The Chat Messaging built into Vicidial is entirely web-based and uses it's own p
UPDATE 2015-12-19: We added several security enhancements related to the chat functionality. We strongly recommend that you update your system to svn/trunk revision 2435 or higher if you are running revision between 2428 and 2434. We also added dynamic language capability throughout the chat screens.
+UPDATE 2016-03-05: We added the ability to transfer a customer chat to another chat group or agent.
+
AGENT CHAT INTERFACE INSTRUCTIONS:
diff --git a/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql b/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql
index 34729dc6..923f7639 100644
--- a/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql
+++ b/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql
@@ -3197,6 +3197,9 @@ status VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
chat_creator VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
group_id VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
lead_id INT(9) UNSIGNED DEFAULT NULL,
+transferring_agent VARCHAR(20),
+user_direct VARCHAR(20),
+user_direct_group_id VARCHAR(20),
PRIMARY KEY (chat_id),
KEY vicidial_chat_archive_lead_id_key (lead_id),
KEY vicidial_chat_archive_start_time_key (chat_start_time)
@@ -3245,6 +3248,9 @@ status VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
chat_creator VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
group_id VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL,
lead_id INT(9) UNSIGNED DEFAULT NULL,
+transferring_agent VARCHAR(20),
+user_direct VARCHAR(20),
+user_direct_group_id VARCHAR(20),
PRIMARY KEY (chat_id),
KEY vicidial_live_chats_lead_id_key (lead_id),
KEY vicidial_live_chats_start_time_key (chat_start_time)
@@ -3494,6 +3500,7 @@ INSERT INTO vicidial_music_on_hold SET moh_id='default',moh_name='Default Music
INSERT INTO vicidial_music_on_hold_files SET moh_id='default',filename='conf',rank='1';
INSERT INTO vicidial_inbound_groups(group_id,group_name,group_color,active,queue_priority) values('AGENTDIRECT','Single Agent Direct Queue','white','Y','99');
+INSERT INTO vicidial_inbound_groups(group_id,group_name,group_color,active,web_form_address,voicemail_ext,next_agent_call,fronter_display,ingroup_script,get_call_launch,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,drop_call_seconds,drop_action,drop_exten,call_time_id,after_hours_action,after_hours_message_filename,after_hours_exten,after_hours_voicemail,welcome_message_filename,moh_context,onhold_prompt_filename,prompt_interval,agent_alert_exten,agent_alert_delay,default_xfer_group,queue_priority,drop_inbound_group,ingroup_recording_override,ingroup_rec_filename,afterhours_xfer_group,qc_enabled,qc_statuses,qc_shift_id,qc_get_record_launch,qc_show_recording,qc_web_form_address,qc_script,play_place_in_line,play_estimate_hold_time,hold_time_option,hold_time_option_seconds,hold_time_option_exten,hold_time_option_voicemail,hold_time_option_xfer_group,hold_time_option_callback_filename,hold_time_option_callback_list_id,hold_recall_xfer_group,no_delay_call_route,play_welcome_message,answer_sec_pct_rt_stat_one,answer_sec_pct_rt_stat_two,default_group_alias,no_agent_no_queue,no_agent_action,no_agent_action_value,web_form_address_two,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,ignore_list_script_override,extension_appended_cidname,uniqueid_status_display,uniqueid_status_prefix,hold_time_option_minimum,hold_time_option_press_filename,hold_time_option_callmenu,hold_time_option_no_block,hold_time_option_prompt_seconds,onhold_prompt_no_block,onhold_prompt_seconds,hold_time_second_option,hold_time_third_option,wait_hold_option_priority,wait_time_option,wait_time_second_option,wait_time_third_option,wait_time_option_seconds,wait_time_option_exten,wait_time_option_voicemail,wait_time_option_xfer_group,wait_time_option_callmenu,wait_time_option_callback_filename,wait_time_option_callback_list_id,wait_time_option_press_filename,wait_time_option_no_block,wait_time_option_prompt_seconds,timer_action_destination,calculate_estimated_hold_seconds,add_lead_url,eht_minimum_prompt_filename,eht_minimum_prompt_no_block,eht_minimum_prompt_seconds,on_hook_ring_time,na_call_url,on_hook_cid,group_calldate,action_xfer_cid,drop_callmenu,after_hours_callmenu,user_group,max_calls_method,max_calls_count,max_calls_action,dial_ingroup_cid,group_handling,web_form_address_three,populate_lead_ingroup,drop_lead_reset,after_hours_lead_reset,nanq_lead_reset,wait_time_lead_reset,hold_time_lead_reset,status_group_id,routing_initiated_recordings,on_hook_cid_number) VALUES ('AGENTDIRECT_CHAT','Agent Direct Queue for Chats','#FFFFFF','Y','','','longest_wait_time','Y','','',NULL,NULL,NULL,NULL,360,'MESSAGE','8307','24hours','MESSAGE','vm-goodbye','8300',NULL,'---NONE---','default','generic_hold',60,'ding',1000,'---NONE---',99,'---NONE---','DISABLED','NONE','---NONE---','N',NULL,'24HRMIDNIGHT','NONE','Y',NULL,NULL,'N','N','NONE',360,'8300','','---NONE---','vm-hangup',0,'---NONE---','N','ALWAYS',20,30,'','N','MESSAGE','nbdy-avail-to-take-call|vm-goodbye','','NONE','',-1,'','','','','','N','N','DISABLED','',0,'to-be-called-back|digits/1','','N',10,'N',10,'NONE','NONE','WAIT','NONE','NONE','NONE',120,'8300','','---NONE---','','vm-hangup',999,'to-be-called-back|digits/1','N',10,'',0,'','','N',10,15,'','GENERIC',NULL,'CUSTOMER','','','---ALL---','DISABLED',0,'DROP','','CHAT','','ENABLED','N','N','N','N','N','','N','');
INSERT INTO vicidial_lists SET list_id='999',list_name='Default inbound list',campaign_id='TESTCAMP',active='N';
INSERT INTO vicidial_lists SET list_id='998',list_name='Default Manual list',campaign_id='TESTCAMP',active='N';
@@ -3713,4 +3720,4 @@ UPDATE vicidial_configuration set value='1766' where name='qc_database_version';
UPDATE system_settings set vdc_agent_api_active='1';
-UPDATE system_settings SET db_schema_version='1452',db_schema_update_date=NOW(),reload_timestamp=NOW();
+UPDATE system_settings SET db_schema_version='1453',db_schema_update_date=NOW(),reload_timestamp=NOW();
diff --git a/agc_2-X/trunk/extras/upgrade_2.12.sql b/agc_2-X/trunk/extras/upgrade_2.12.sql
index ea99df25..ad3bdbc0 100644
--- a/agc_2-X/trunk/extras/upgrade_2.12.sql
+++ b/agc_2-X/trunk/extras/upgrade_2.12.sql
@@ -512,3 +512,15 @@ UPDATE system_settings SET db_schema_version='1451',db_schema_update_date=NOW()
ALTER TABLE system_settings ADD report_default_format ENUM('TEXT', 'HTML') default 'TEXT';
UPDATE system_settings SET db_schema_version='1452',db_schema_update_date=NOW() where db_schema_version < 1452;
+
+ALTER TABLE vicidial_live_chats ADD transferring_agent VARCHAR(20);
+ALTER TABLE vicidial_live_chats ADD user_direct VARCHAR(20);
+ALTER TABLE vicidial_live_chats ADD user_direct_group_id VARCHAR(20);
+
+ALTER TABLE vicidial_chat_archive ADD transferring_agent VARCHAR(20);
+ALTER TABLE vicidial_chat_archive ADD user_direct VARCHAR(20);
+ALTER TABLE vicidial_chat_archive ADD user_direct_group_id VARCHAR(20);
+
+INSERT INTO vicidial_inbound_groups(group_id,group_name,group_color,active,web_form_address,voicemail_ext,next_agent_call,fronter_display,ingroup_script,get_call_launch,xferconf_a_dtmf,xferconf_a_number,xferconf_b_dtmf,xferconf_b_number,drop_call_seconds,drop_action,drop_exten,call_time_id,after_hours_action,after_hours_message_filename,after_hours_exten,after_hours_voicemail,welcome_message_filename,moh_context,onhold_prompt_filename,prompt_interval,agent_alert_exten,agent_alert_delay,default_xfer_group,queue_priority,drop_inbound_group,ingroup_recording_override,ingroup_rec_filename,afterhours_xfer_group,qc_enabled,qc_statuses,qc_shift_id,qc_get_record_launch,qc_show_recording,qc_web_form_address,qc_script,play_place_in_line,play_estimate_hold_time,hold_time_option,hold_time_option_seconds,hold_time_option_exten,hold_time_option_voicemail,hold_time_option_xfer_group,hold_time_option_callback_filename,hold_time_option_callback_list_id,hold_recall_xfer_group,no_delay_call_route,play_welcome_message,answer_sec_pct_rt_stat_one,answer_sec_pct_rt_stat_two,default_group_alias,no_agent_no_queue,no_agent_action,no_agent_action_value,web_form_address_two,timer_action,timer_action_message,timer_action_seconds,start_call_url,dispo_call_url,xferconf_c_number,xferconf_d_number,xferconf_e_number,ignore_list_script_override,extension_appended_cidname,uniqueid_status_display,uniqueid_status_prefix,hold_time_option_minimum,hold_time_option_press_filename,hold_time_option_callmenu,hold_time_option_no_block,hold_time_option_prompt_seconds,onhold_prompt_no_block,onhold_prompt_seconds,hold_time_second_option,hold_time_third_option,wait_hold_option_priority,wait_time_option,wait_time_second_option,wait_time_third_option,wait_time_option_seconds,wait_time_option_exten,wait_time_option_voicemail,wait_time_option_xfer_group,wait_time_option_callmenu,wait_time_option_callback_filename,wait_time_option_callback_list_id,wait_time_option_press_filename,wait_time_option_no_block,wait_time_option_prompt_seconds,timer_action_destination,calculate_estimated_hold_seconds,add_lead_url,eht_minimum_prompt_filename,eht_minimum_prompt_no_block,eht_minimum_prompt_seconds,on_hook_ring_time,na_call_url,on_hook_cid,group_calldate,action_xfer_cid,drop_callmenu,after_hours_callmenu,user_group,max_calls_method,max_calls_count,max_calls_action,dial_ingroup_cid,group_handling,web_form_address_three,populate_lead_ingroup,drop_lead_reset,after_hours_lead_reset,nanq_lead_reset,wait_time_lead_reset,hold_time_lead_reset,status_group_id,routing_initiated_recordings,on_hook_cid_number) VALUES ('AGENTDIRECT_CHAT','Agent Direct Queue for Chats','#FFFFFF','Y','','','longest_wait_time','Y','','',NULL,NULL,NULL,NULL,360,'MESSAGE','8307','24hours','MESSAGE','vm-goodbye','8300',NULL,'---NONE---','default','generic_hold',60,'ding',1000,'---NONE---',99,'---NONE---','DISABLED','NONE','---NONE---','N',NULL,'24HRMIDNIGHT','NONE','Y',NULL,NULL,'N','N','NONE',360,'8300','','---NONE---','vm-hangup',0,'---NONE---','N','ALWAYS',20,30,'','N','MESSAGE','nbdy-avail-to-take-call|vm-goodbye','','NONE','',-1,'','','','','','N','N','DISABLED','',0,'to-be-called-back|digits/1','','N',10,'N',10,'NONE','NONE','WAIT','NONE','NONE','NONE',120,'8300','','---NONE---','','vm-hangup',999,'to-be-called-back|digits/1','N',10,'',0,'','','N',10,15,'','GENERIC',NULL,'CUSTOMER','','','---ALL---','DISABLED',0,'DROP','','CHAT','','ENABLED','N','N','N','N','N','','N','');
+
+UPDATE system_settings SET db_schema_version='1453',db_schema_update_date=NOW() where db_schema_version < 1453;
diff --git a/agc_2-X/trunk/install.pl b/agc_2-X/trunk/install.pl
index 7bfb0c9f..df122524 100644
--- a/agc_2-X/trunk/install.pl
+++ b/agc_2-X/trunk/install.pl
@@ -2421,7 +2421,7 @@ print conf "# 5 - AST_VDadapt (If multi-server system, this must only be on one
print conf "# 6 - FastAGI_log\n";
print conf "# 7 - AST_VDauto_dial_FILL (only for multi-server, this must only be on one server)\n";
print conf "# 8 - ip_relay (used for blind agent monitoring)\n";
-print conf "# 9 - Timeclock auto logout\n";
+print conf "# 9 - Timeclock auto logout, (If multi-server system, this must only be on one server)\n";
print conf "# E - Email processor, (If multi-server system, this must only be on one server)\n";
print conf "VARactive_keepalives => $VARactive_keepalives\n";
print conf "\n";
diff --git a/agc_2-X/trunk/www/agc/chat_db_query.php b/agc_2-X/trunk/www/agc/chat_db_query.php
index 20f3b521..ce86db0d 100644
--- a/agc_2-X/trunk/www/agc/chat_db_query.php
+++ b/agc_2-X/trunk/www/agc/chat_db_query.php
@@ -15,6 +15,7 @@
# 151231-0841 - Added agent_allowed_chat_groups setting
# 160107-2318 - Bug fix for agent ending chat with manager
# 160108-2300 - Changed some mysqli_query to mysql_to_mysqli for consistency
+# 160303-0051 - Added code for chat transfers
#
require("dbconnect_mysqli.php");
@@ -79,6 +80,10 @@ if (isset($_GET["manager_message"])) {$manager_message=$_GET["manager_messag
elseif (isset($_POST["manager_message"])) {$manager_message=$_POST["manager_message"];}
if (isset($_GET["ChatReloadIDNumber"])) {$ChatReloadIDNumber=$_GET["ChatReloadIDNumber"];}
elseif (isset($_POST["ChatReloadIDNumber"])) {$ChatReloadIDNumber=$_POST["ChatReloadIDNumber"];}
+if (isset($_GET["chat_xfer_type"])) {$chat_xfer_type=$_GET["chat_xfer_type"];}
+ elseif (isset($_POST["chat_xfer_type"])) {$chat_xfer_type=$_POST["chat_xfer_type"];}
+if (isset($_GET["chat_xfer_value"])) {$chat_xfer_value=$_GET["chat_xfer_value"];}
+ elseif (isset($_POST["chat_xfer_value"])) {$chat_xfer_value=$_POST["chat_xfer_value"];}
$chat_member_name = preg_replace('/[^- \.\,\_0-9a-zA-Z]/',"",$chat_member_name);
if (!$user) {echo "No user, no using."; exit;}
@@ -549,6 +554,91 @@ if ($action=="agent_send_message" && $chat_id) {
}
}
+if ($action=="xfer_chat" && $user && $chat_id && $chat_xfer_value && $chat_xfer_type) {
+ $stmt="select group_id from vicidial_live_chats where chat_id='$chat_id'";
+ $rslt=mysql_to_mysqli($stmt, $link);
+ if (mysqli_num_rows($rslt)==0) {
+ echo "ERROR";
+ exit;
+ } else {
+ $row=mysqli_fetch_row($rslt);
+ $group_id=$row[0];
+ }
+
+ if ($chat_xfer_type=="group") {
+ $upd_stmt="update vicidial_live_chats set group_id='$chat_xfer_value', status='WAITING', chat_creator='NONE', transferring_agent='$user' where chat_id='$chat_id'";
+ $upd_rslt=mysql_to_mysqli($upd_stmt, $link);
+ } else {
+ $upd_stmt="update vicidial_live_chats set group_id='AGENTDIRECT_CHAT', user_direct='$chat_xfer_value', user_direct_group_id='$group_id', status='WAITING', transferring_agent='$user' where chat_id='$chat_id'";
+ $upd_rslt=mysql_to_mysqli($upd_stmt, $link);
+ }
+ echo mysqli_affected_rows($link)."|";
+
+ if (mysqli_affected_rows($link)==1) {
+ $log_upd_stmt="insert into vicidial_chat_log(chat_id, message, message_time, poster, chat_member_name, chat_level) VALUES('$chat_id', 'Chat transferred to ".strtoupper($chat_xfer_type)." ".strtoupper($chat_xfer_value)."', now(), '$user', '".mysqli_real_escape_string($link, $chat_member_name)."', '1')";
+ $log_upd_rslt=mysql_to_mysqli($log_upd_stmt, $link);
+
+ $upd_stmt="UPDATE vicidial_live_agents set status='PAUSED',comments='',external_hangup=0,external_status='',external_pause='',external_dial='',last_state_change='$NOW_TIME',pause_code='' where user='$user' and server_ip='$server_ip' and status='INCALL' and comments='CHAT'";
+ $upd_rslt=mysql_to_mysqli($upd_stmt, $link);
+
+ $del_stmt="delete from vicidial_chat_participants where chat_member='$user' and chat_id='$chat_id'";
+ $del_rslt=mysql_to_mysqli($del_stmt, $link);
+
+ $vla_stmt="select closer_campaigns from vicidial_live_agents where user='$user'";
+ $vla_rslt=mysql_to_mysqli($vla_stmt, $link);
+ echo "
";
+ echo "
";
+ echo "|"; // DO NOT ECHO TOGGLE DIAL CONTROL HERE. WE DO NOT WANT THE AGENT'S PAUSE BUTTON REACTIVATED YET.
+ }
+/*
+vicidial_live_chats
++---------+---------------------+--------+--------------+----------+---------+
+| chat_id | chat_start_time | status | chat_creator | group_id | lead_id |
++---------+---------------------+--------+--------------+----------+---------+
+| 516 | 2015-12-18 12:04:54 | LIVE | 6666 | MIKECHAT | 1079414 |
+| 517 | 2015-12-18 12:13:48 | LIVE | 6666 | MIKECHAT | 1079414 |
+| 510 | 2015-12-18 09:23:09 | LIVE | 6666 | MIKECHAT | 1079414 |
++---------+---------------------+--------+--------------+----------+---------+
+
+vicidial_chat_participants
++---------------------+-----------------+------+-----+---------+----------------+
+| Field | Type | Null | Key | Default | Extra |
++---------------------+-----------------+------+-----+---------+----------------+
+| chat_participant_id | int(9) unsigned | NO | PRI | NULL | auto_increment |
+| chat_id | int(9) unsigned | YES | MUL | NULL | |
+| chat_member | varchar(20) | YES | | NULL | |
+| chat_member_name | varchar(100) | YES | | NULL | |
+| ping_date | datetime | YES | | NULL | |
+| vd_agent | enum('Y','N') | YES | | N | |
++---------------------+-----------------+------+-----+---------+----------------+
+
+vicidial_chat_log
++----------------+---------+----------------------------+---------------------+--------+------------------+------------+
+| message_row_id | chat_id | message | message_time | poster | chat_member_name | chat_level |
++----------------+---------+----------------------------+---------------------+--------+------------------+------------+
+| 530 | 517 | Harold Smith has left chat | 2015-12-18 12:19:53 | 6666 | Admin | 1 |
+| 529 | 516 | Harold Smith has left chat | 2015-12-18 12:06:09 | 6666 | Admin | 1 |
+| 513 | 510 | Harold Smith has left chat | 2015-12-18 09:26:17 | 6666 | Admin | 1 |
++----------------+---------+----------------------------+---------------------+--------+------------------+------------+
+
+*/
+}
+
+
if ($action=="agent_leave_chat" && $user && $chat_id) {
$del_stmt2="delete from vicidial_chat_participants where chat_id='$chat_id' and chat_member='$user'";
$del_rslt2=mysql_to_mysqli($del_stmt2, $link);
@@ -730,8 +820,107 @@ if ($action=="send_invite" && $chat_id && $email && $chat_group_id) {
}
}
+if ($action=="load_xfer_options" && $user && $chat_group_id) {
+ $vla_stmt="select vla.campaign_id, vug.agent_allowed_chat_groups from vicidial_live_agents vla, vicidial_users vu, vicidial_user_groups vug where vla.user='$user' and vla.user=vu.user and vu.user_group=vug.user_group";
+ $vla_rslt=mysql_to_mysqli($vla_stmt, $link);
+ if (mysqli_num_rows($vla_rslt)>0) {
+ $vla_row=mysqli_fetch_row($vla_rslt);
+ $user_campaign_id=trim($vla_row[0]);
+ $allowed_chat_user_groups=trim($vla_row[1]);
+ }
+
+ $xfer_group_stmt="select xfer_groups from vicidial_campaigns where campaign_id='$user_campaign_id'";
+ $xfer_group_rslt=mysql_to_mysqli($xfer_group_stmt, $link);
+ if (mysqli_num_rows($xfer_group_rslt)>0) {
+ $xfer_row=mysqli_fetch_row($xfer_group_rslt);
+ $xfer_groups=trim($xfer_row[0]);
+ $xfer_groups=preg_replace('/\s/', '\',\'', $xfer_groups);
+ $xfer_groups_SQL="'".$xfer_groups."'";
+ }
+
+ $chat_groups_array=array();
+ $chat_group_names_array=array();
+ $chat_agents_array=array();
+ $chat_agent_names_array=array();
+
+ $group_stmt="select group_id, group_name from vicidial_inbound_groups where group_handling='CHAT' and group_id in ($xfer_groups_SQL) order by group_name asc";
+ $group_rslt=mysql_to_mysqli($group_stmt, $link);
+ if (mysqli_num_rows($group_rslt)>0) {
+ while ($group_row=mysqli_fetch_row($group_rslt)) {
+ # echo "";
+ array_push($chat_groups_array, $group_row[0]);
+ array_push($chat_group_names_array, $group_row[1]);
+ }
+ } else {
+ array_push($chat_groups_array, "");
+ array_push($chat_group_names_array, "** "._QXZ("NO AVAILABLE GROUPS")." **");
+ }
+
+ echo implode("|", $chat_groups_array)."\n".implode("|", $chat_group_names_array);
+ echo "\n";
+
+ $user_group_SQL="";
+ if (preg_match('/\-\-CAMPAIGN\-AGENTS\-\-/')) {
+ $user_group_SQL.="vla.campaign_id='$user_campaign_id' or ";
+ $allowed_chat_user_groups=trim(preg_replace('/\-\-CAMPAIGN\-AGENTS\-\-/', '', $allowed_chat_user_groups));
+ }
+ if (!preg_match('/\-\-ALL\-GROUPS\-\-/', $allowed_chat_user_groups)) {
+ $allowed_chat_user_groups=preg_replace('/\s/', '\',\'', $allowed_chat_user_groups);
+ $user_group_SQL.="vu.user_group in ('$allowed_chat_user_groups')";
+ } else {
+ $user_group_SQL.="vu.user_group not in ('')";
+ }
+ $user_group_SQL=preg_replace('/ or $/', '', $user_group_SQL);
+ if (strlen($user_group_SQL)>0) {
+ $available_agents_SQL="and ($user_group_SQL)";
+ } else {
+ $available_agents_SQL="";
+ }
+
+ $agent_stmt="select vu.user, full_name from vicidial_live_agents vla, vicidial_users vu, vicidial_campaigns vc where vla.user!='$user' and vla.user=vu.user and vla.campaign_id=vc.campaign_id and vc.allow_chats='Y' $available_agents_SQL order by full_name asc";
+ $agent_rslt=mysql_to_mysqli($agent_stmt, $link);
+ if (mysqli_num_rows($agent_rslt)>0) {
+ while ($agent_row=mysqli_fetch_row($agent_rslt)) {
+# echo "";
+ array_push($chat_agents_array, $agent_row[0]);
+ array_push($chat_agent_names_array, $agent_row[1]);
+ }
+ } else {
+ array_push($chat_agents_array, "");
+ array_push($chat_agent_names_array, "** "._QXZ("NO AVAILABLE AGENTS")." **");
+ }
+
+ echo implode("|", $chat_agents_array)."\n".implode("|", $chat_agent_names_array);
+
+}
+
if ($action=="end_chat" && $chat_id && $chat_creator && $user && $server_ip) {
- if ($user!=$chat_creator) {
+ # Check that chat is actually ending by the agent and not a transfer
+ if ($chat_creator=="XFER") {
+ echo "Leaving XFER|";
+ # At this point this should only be coming from the 'HANGUP CUSTOMER' button, so once that is clicked it is safe to make the 'START CHAT' available again.
+ $vla_stmt="select closer_campaigns from vicidial_live_agents where user='$user'";
+ $vla_rslt=mysql_to_mysqli($vla_stmt, $link);
+ echo "
";
+ echo "
";
+ echo "|TOGGLE_DIAL_CONTROL";
+
+ exit;
+ } else if ($user!=$chat_creator) {
echo _QXZ("You cannot end this chat unless you are the one who started it.");
exit;
}
diff --git a/agc_2-X/trunk/www/agc/conf_exten_check.php b/agc_2-X/trunk/www/agc/conf_exten_check.php
index 5b38ebbd..2d02ff50 100644
--- a/agc_2-X/trunk/www/agc/conf_exten_check.php
+++ b/agc_2-X/trunk/www/agc/conf_exten_check.php
@@ -71,10 +71,11 @@
# 150904-2138 - Added SQL features for chats started via agent invite, modified output
# 160104-1232 - Added proper detection of dead chats, disabled dead detection of emails
# 160227-1007 - Fixed XSS security issue, issue #929
+# 160303-2354 - Added code for chat transfers
#
-$version = '2.12-46';
-$build = '160227-1007';
+$version = '2.12-47';
+$build = '160303-2354';
$php_script = 'conf_exten_check.php';
$mel=1; # Mysql Error Log enabled = 1
$mysql_log_count=44;
@@ -396,7 +397,7 @@ if ($ACTION == 'refresh')
}
else
{
- $chat_stmt="select count(*) from vicidial_live_chats where status='WAITING' and (group_id IN('$AccampSQL')) and chat_creator!='$user'";
+ $chat_stmt="select count(*) from vicidial_live_chats where status='WAITING' and ((group_id IN('$AccampSQL') and (transferring_agent is null or transferring_agent!='$user')) or (group_id='AGENTDIRECT_CHAT' and user_direct='$user')) and chat_creator!='$user'";
$chat_rslt=mysql_to_mysqli($chat_stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$chat_stmt,'03041',$user,$server_ip,$session_name,$one_mysql_log);}
$chat_row=mysqli_fetch_row($chat_rslt);
diff --git a/agc_2-X/trunk/www/agc/vdc_chat_display.php b/agc_2-X/trunk/www/agc/vdc_chat_display.php
index be972429..6617c79d 100644
--- a/agc_2-X/trunk/www/agc/vdc_chat_display.php
+++ b/agc_2-X/trunk/www/agc/vdc_chat_display.php
@@ -1,7 +1,7 @@
LICENSE: AGPLv2
+# Copyright (C) 2016 Joe Johnson, Matt Florell LICENSE: AGPLv2
#
# This is the interface for agents to chat with customers and each other. It's separate from the manager-to-agent
# chat interface out of necessity and calls the chat_db_query.php page to send information and display it. It will
@@ -14,6 +14,7 @@
# 150903-2349 - First build
# 151213-1107 - Added variable filtering
# 151218-0913 - Added missing translation code and user auth
+# 160303-0051 - Added code for chat transfers
#
require("dbconnect_mysqli.php");
@@ -535,7 +536,7 @@ function EndChat(hangup_override) { // hangup_override comes from parent Iframe
if (!chat_creator || !user || !chat_id) {
return false;
- } else if (user!=chat_creator) {
+ } else if (user!=chat_creator && chat_creator!='XFER') {
chat_alert_box("");
return false;
}
@@ -605,6 +606,158 @@ function ShowHideMembers(menuName, chat_id) {
}
}
+function ToggleSpan(span_name) {
+ var span_vis = document.getElementById(span_name).style;
+ if (span_vis.display=='none') { span_vis.display = 'block'; } else { span_vis.display = 'none'; }
+}
+
+function LoadXferOptions() {
+ var chat_group_id=document.getElementById('chat_group_id').value;
+ var user=document.getElementById('user').value;
+ var pass=document.getElementById('pass').value;
+
+ // Clear select menus
+ var GroupOptions = document.getElementById("ChatXferGroups");
+ while (GroupOptions.length > 1) {
+ GroupOptions.remove(GroupOptions.length-1);
+ }
+ var AgentOptions = document.getElementById("ChatXferAgents");
+ while (AgentOptions.length > 1) {
+ AgentOptions.remove(AgentOptions.length-1);
+ }
+
+ var xmlhttp=false;
+ if (!xmlhttp && typeof XMLHttpRequest!='undefined')
+ {
+ xmlhttp = new XMLHttpRequest();
+ }
+ if (xmlhttp)
+ {
+ chat_query = "&action=load_xfer_options&user="+user+"&pass="+pass+"&lead_id="+lead_id+"&server_ip="+server_ip+"&chat_group_id="+chat_group_id;
+ xmlhttp.open('POST', 'chat_db_query.php');
+ xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
+ xmlhttp.send(chat_query);
+ xmlhttp.onreadystatechange = function()
+ {
+ if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
+ {
+ var xfer_options = xmlhttp.responseText;
+ if (xfer_options!="")
+ {
+ var xfer_options_array=xfer_options.split("\n");
+ var groups_array=xfer_options_array[0].split("|");
+ var group_names_array=xfer_options_array[1].split("|");
+ var agents_array=xfer_options_array[2].split("|");
+ var agent_names_array=xfer_options_array[3].split("|");
+/*
+ var opt = document.createElement('option');
+ opt.value = "";
+ opt.innerHTML = "";
+ GroupOptions.appendChild(opt);
+
+ var opt = document.createElement('option');
+ opt.value = "";
+ opt.innerHTML = "";
+ AgentOptions.appendChild(opt);
+*/
+ for (var i = 0; i0 && selAgent>0))
+ {
+ return false;
+ }
+ else
+ {
+ if (selGroup>0)
+ {
+ var chat_xfer_value=document.getElementById("ChatXferGroups").options[selGroup].value;
+ var chat_xfer_type="group";
+ }
+ else
+ {
+ var chat_xfer_value=document.getElementById("ChatXferAgents").options[selAgent].value;
+ var chat_xfer_type="agent";
+ }
+ }
+
+ var xmlhttp=false;
+ if (!xmlhttp && typeof XMLHttpRequest!='undefined')
+ {
+ xmlhttp = new XMLHttpRequest();
+ }
+ if (xmlhttp)
+ {
+ chat_query = "&action=xfer_chat&chat_member_name="+chat_member_name+"&user="+user+"&pass="+pass+"&lead_id="+lead_id+"&chat_id="+chat_id+"&server_ip="+server_ip+"&chat_xfer_value="+chat_xfer_value+"&chat_xfer_type="+chat_xfer_type;
+ xmlhttp.open('POST', 'chat_db_query.php');
+ xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
+ xmlhttp.send(chat_query);
+ xmlhttp.onreadystatechange = function()
+ {
+ if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
+ {
+ var xfer_result_data = xmlhttp.responseText;
+ var xfer_result=xfer_result_data.split("|");
+ if (xfer_result[0]==0)
+ {
+ alert("");
+ }
+ else if (xfer_result[0]>1)
+ {
+ alert("");
+ }
+ else
+ {
+ document.getElementById('chat_creator_console').innerHTML=''; // DO NOT MAKE ANY BUTTONS AVAILABLE AT THIS POINT FOR ENDING OR STARTING A CHAT!
+ document.getElementById('ChatConsoleSpan').style.display='none';
+ document.getElementById('XferConsoleSpan').style.display='none';
+ document.getElementById('chat_group_id').value='';
+ document.getElementById('chat_creator').value='XFER';
+ // IF AGENT NEVER INVITED SOMEONE, THERE'S NO LEAD ATTACHED AND IT'S SAFE FOR THEM TO JUST GO BACK TO BEING PAUSED WITHOUT HAVING TO DO ANYTHING ELSE.
+ // HOWEVER, SINCE WE DEACTIVATED THE PAUSE BUTTON FROM THE StartChat() FUNCTION WE NEED TO REACTIVATE IT IN PAUSED MODE.
+ if (xfer_result[2]=="TOGGLE_DIAL_CONTROL")
+ {
+ if (dial_method=="INBOUND_MAN")
+ {
+ window.parent.document.getElementById("DiaLControl").innerHTML = DiaLControl_inbound_manual_HTML;
+ }
+ else
+ {
+ window.parent.document.getElementById("DiaLControl").innerHTML = DiaLControl_auto_HTML;
+ }
+ }
+ UpdateChatWindow();
+ }
+ }
+ }
+ }
+}
+
window.onbeforeunload = LeaveChat;
@@ -663,9 +816,10 @@ if($child_window) {
0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00337',$user,$server_ip,$session_name,$one_mysql_log);}
@@ -7977,7 +7978,7 @@ if ($ACTION == 'VDADcheckINCOMINGother')
$INclosecallid='';
$INxfercallid='';
$email_group_str='';
- $chat_group_str='';
+ $chat_group_str="";
$VLA_inOUT='NONE';
$queue_seconds=0;
@@ -8033,7 +8034,8 @@ if ($ACTION == 'VDADcheckINCOMINGother')
### If no emails have been sent to agent, check for chats, this is the code section where the agent interface will grab the next available chat
if ($email_ct==0)
{
- $stmt="SELECT chat_id,UNIX_TIMESTAMP(chat_start_time),status,chat_creator,group_id,lead_id from vicidial_live_chats where status='WAITING' and group_id in ($chat_group_str) order by chat_id asc limit 1;";
+ # Chats don't have a priority setting, but we use it for the AGENTDIRECT_CHAT one (which has it set to 99 and is uneditable through the admin) so that is always the highest priority. Also ensures that agent does not transfer to self if transferring to the same ingroup (transferring_agent!=user clause)
+ $stmt="SELECT vlc.chat_id,UNIX_TIMESTAMP(vlc.chat_start_time),vlc.status,vlc.chat_creator,vlc.group_id,vlc.lead_id,vlc.user_direct_group_id,vig.queue_priority from vicidial_live_chats vlc, vicidial_inbound_groups vig where vlc.status='WAITING' and (vlc.group_id in ($chat_group_str) or (vlc.group_id='AGENTDIRECT_CHAT' and user_direct='$user')) and (transferring_agent is null or transferring_agent!='$user') order by queue_priority desc, chat_id asc limit 1;";
if ($DB) {echo "$stmt\n";}
$rslt=mysql_to_mysqli($stmt, $link);
if ($mel > 0) {mysql_error_logging($NOW_TIME,$link,$mel,$stmt,'00638',$user,$server_ip,$session_name,$one_mysql_log);}
@@ -8047,8 +8049,12 @@ if ($ACTION == 'VDADcheckINCOMINGother')
$group_id = $chat_row[4];
$VDADchannel_group = $chat_row[4];
$lead_id = $chat_row[5];
+ $user_direct_group_id = $chat_row[6];
$uniqueid=date("U").".".rand(1, 9999);
- $upd_stmt="update vicidial_live_chats set status='LIVE', chat_creator='$user' where chat_id='$chat_id'";
+ # If this is a transfer directly to an agent, the group ID is 'AGENTDIRECT_CHAT', and we need to set this back to the group ID it was prior to coming over (maybe)
+ if ($group_id=="AGENTDIRECT_CHAT") {$upd_clause=", group_id='$user_direct_group_id'";} else {$upd_clause="";}
+
+ $upd_stmt="update vicidial_live_chats set status='LIVE', chat_creator='$user'$upd_clause where chat_id='$chat_id'";
$upd_rslt=mysql_to_mysqli($upd_stmt, $link);
$chat_ct=mysqli_affected_rows($link);
}
diff --git a/agc_2-X/trunk/www/chat_customer/customer_chat_functions.php b/agc_2-X/trunk/www/chat_customer/customer_chat_functions.php
index 7882b730..63eb5677 100644
--- a/agc_2-X/trunk/www/chat_customer/customer_chat_functions.php
+++ b/agc_2-X/trunk/www/chat_customer/customer_chat_functions.php
@@ -9,6 +9,7 @@
# 160108-1710 - Added available_agents variable
# 160120-1943 - Added show_email variable
# 160203-1051 - Added display of chat message after ending it
+# 160303-0055 - Added code for chat transfers
#
require("dbconnect_mysqli.php");
@@ -165,11 +166,18 @@ if ($action=="leave_chat" && $user && $chat_id) {
$upd_stmt="UPDATE vicidial_list set status='CDROP' where lead_id='$lead_id'";
$upd_rslt=mysql_to_mysqli($upd_stmt, $link);
- $ins_stmt="INSERT IGNORE INTO vicidial_chat_archive SELECT chat_id, chat_start_time, 'DROP', chat_creator, group_id, lead_id From vicidial_live_chats where chat_id='$chat_id'";
+ $ins_stmt="INSERT IGNORE INTO vicidial_chat_archive SELECT chat_id, chat_start_time, 'DROP', chat_creator, group_id, lead_id, transferring_agent, user_direct, user_direct_group_id From vicidial_live_chats where chat_id='$chat_id'";
$ins_rslt=mysql_to_mysqli($ins_stmt, $link);
$del_stmt="DELETE from vicidial_live_chats where chat_id='$chat_id'";
$del_rslt=mysql_to_mysqli($del_stmt, $link);
+
+ # ARCHIVE CHAT IN CASE CUSTOMER IS LEAVING WHILE BEING TRANSFERRED
+ $archive_log_stmt="insert ignore into vicidial_chat_log_archive select * from vicidial_chat_log where chat_id='$chat_id'";
+ $archive_log_rslt=mysql_to_mysqli($archive_log_stmt, $link);
+
+ $del_log_stmt="delete from vicidial_chat_log where chat_id='$chat_id'";
+ $del_log_rslt=mysql_to_mysqli($del_log_stmt, $link);
} else {
# CHAT IS LIVE/AGENT NEEDS NOTIFICATION
$ins_alert_stmt="INSERT INTO vicidial_chat_log(poster, chat_member_name, message_time, message, chat_id, chat_level) SELECT '$chat_creator', full_name, now(), '$chat_member_name has left chat', '$chat_id', '1' from vicidial_users where user='$chat_creator'";
@@ -180,7 +188,7 @@ if ($action=="leave_chat" && $user && $chat_id) {
}
if ($action=="update_chat_window" && $chat_id) {
- $status_stmt="SELECT status, chat_creator from vicidial_live_chats where chat_id='$chat_id'";
+ $status_stmt="SELECT status, chat_creator, transferring_agent from vicidial_live_chats where chat_id='$chat_id'";
$status_rslt=mysql_to_mysqli($status_stmt, $link);
if (mysqli_num_rows($status_rslt)==0) {
# JCJ - comment out to display in Javascript function that calls this in parent page.
@@ -217,8 +225,8 @@ if ($action=="update_chat_window" && $chat_id) {
}
## CHECK IF CHAT IS ACTIVE, IF SO GRAB DISTINCT USERS IN ORDER OF POST TO ASSIGN COLORS
- if ($status_row[0]=="LIVE") {
- $live_stmt="SELECT * from vicidial_live_chats vlc, vicidial_chat_participants vcp where vlc.chat_id='$chat_id' and status='LIVE' and vlc.chat_id=vcp.chat_id and vcp.chat_member='$user'";
+ if ($status_row[0]=="LIVE" || ($status_row[0]=="WAITING" && $status_row[2]!="")) {
+ $live_stmt="SELECT * from vicidial_live_chats vlc, vicidial_chat_participants vcp where vlc.chat_id='$chat_id' and (status='LIVE' or (status='WAITING' and transferring_agent is not null)) and vlc.chat_id=vcp.chat_id and vcp.chat_member='$user'";
$live_rslt=mysql_to_mysqli($live_stmt, $link);
if (mysqli_num_rows($live_rslt)>0) {
echo ""._QXZ("Current chat").": $chat_id \n";
@@ -246,6 +254,10 @@ if ($action=="update_chat_window" && $chat_id) {
echo "