diff --git a/agc_2-X/trunk/UPGRADE b/agc_2-X/trunk/UPGRADE index 733bb02b..64ee58b3 100644 --- a/agc_2-X/trunk/UPGRADE +++ b/agc_2-X/trunk/UPGRADE @@ -578,6 +578,10 @@ OTHER CHANGES: values when adding new phones through admin.php. Also added a Copy New Phone admin web function. +164. Redesign of QC module, with new QC scorecards, the ability to do QC by + Campaign/List/In-Group, new reporting and more. See the + docs/QC_PROCCES.txt document for more information. + diff --git a/agc_2-X/trunk/docs/QC_PROCESS.txt b/agc_2-X/trunk/docs/QC_PROCESS.txt index 66f7772f..18b7d789 100644 --- a/agc_2-X/trunk/docs/QC_PROCESS.txt +++ b/agc_2-X/trunk/docs/QC_PROCESS.txt @@ -1,4 +1,119 @@ -QC(Quality Control) process flow 2012-11-16 +QC(Quality Control) process flow 2021-03-09 + +This document covers the QC module features as of admin.php build 210306-0840 +(svn/trunk revision 3368). For information on the previous version of the QC +Module, see the PREVIOUS VERSIONS section further down in this document. + + + + +Vicidial Quality Control Setup and Use Overview - + +General steps (details below): +1. Enable QC features through the System Settings. + 1a. (optional) modify "QC Claim Limit" and "QC Expire Days" +2. Create and modify QC status templates through the "Settings Containers" section of the Vicidial admin. +3. Create and modify QC scorecards through the QC scorecard section under the "Quality Control" menu. +4. Apply scorecard, webform, and status template settings to campaigns, lists, and ingroups as needed +5. As qualifying calls are made, they appear in the QC queue and can be claimed by any agent with the appropriate privileges. +6. Agents use the quality control interface to evaluate calls by listening to the recording associated with the call, and assigning scores to the checkpoints defined in the scorecard. + 6a. Additionally, agents can modify lead information through the quality control interface as well as listen to other recordings associated with the lead and view call log and quality control change logs + 6b. Agents can also place calls to the lead they're evaluating provided they're already logged into the agent interface in a separate browser window +7. Admin users can use the "Quality Control Report" to review quality control calls that are in progress or finished. + + + + +STEP 1. Admin -> System Settings + +No quality control features can be accessed at all unless the "QC Features enabled" System Setting is activated. This is located in the "System Settings" page, along with the related system settings of "QC Claim Limit" and "QC Expire Days". + +"QC Claim Limit" places a limit on the number of unfinished calls an individual agent can have in their queue at one time. The purpose of this setting is both to prevent a single agent from monopolizing the calls in a queue, and also to ensure that claimed calls are handled relatively promptly. + +"QC Expire Days" puts a limit on the number of days a call will be available to be claimed by an agent, after which it will no longer be available for review if it stays unclaimed. However, once a call is claimed it does not expire (unless the agent releases it from their queue after the expiration date has passed). + +To start funneling qualifying calls into the quality control queue, a campaign, ingroup, and/or a list must have a QC status template and a QC scorecard assigned to it. Then there must be a call whose disposition is given in the applied status template and the call will appear in the quality control queue. + + +STEP 2. QC status templates +A quality control status template can be created as a settings container of the type "QC_TEMPLATE". All it needs to consist of is a comma-delimited list of dispositions. Once created and activated, it will be available for selection anywhere the status template is set. + + +STEP 3. QC Scorecards +A scorecard is a list of checkpoints, each assigned a point value, that an agent follows as they are reviewing a call. A scorecard must consist of at least one checkpoint and be active in order for it to be appear as an option when applying quality control settings to entities. To start creating a scorecard, go to the QC Scorecards page - the link can be found under the "Quality Control" menu. +Click "ADD NEW SCORECARD", which will bring up a simple three-field form where you give the scorecard ID, name, and whether or not the scorecard is active. Clicking "SUBMIT NEW SCORECARD" will cause the new scorecard to appear at the top of the screen. At this point you can de/activate the scorecard, modify it, or delete it. Once created, scorecards can be de/activated simply by checking or unchecking the "Active" checkbox for each scorecard - no form submission is necessary. Clicking the "DELETE" button will cause the screen to prompt you to confirm that you do want to proceed with deleting the scorecard, similar to deleting other dialer entities such as campaigns or lists. + +Clicking "MODIFY" by any scorecard will display the checkpoints for that scorecard below the list of created scorecards, along with an extra form for adding new checkpoints. A checkpoint consists of the following elements: + - Order - this is the order in which the checkpoints will be displayed on screen. + - Active - much like the scorecard itself, individual checkpoints can be activated and de-activated as needed. When a checkpoint is deactivated, if a call is assigned to it's parent scorecard, that checkpoint will not appear on the QC evaluation page. Additionally, re-activating the checkpoint will not retroactively add the checkpoint to already-claimed calls; claimed calls must be released and re-claimed if activated checkpoints need to be shown for said calls. + - Checkpoint text - the text displayed to the QC agents + - Points - The maximum score a checkpoint is worth. QC agents can enter any integer value that is this score or lower, with a minimum limit of zero. + - Instant kill - If this is activated, a checkpoint can automatically fail a quality control record regardless of the outcome of any and all other checkpoints. + - Admin notes - Admin notes are comments that administrators can make regarding a checkpoint. This is never viewable to the QC agent. + +If the above fields are filled out in the "ADD NEW CHECKPOINT" section, clicking the green "ADD" button will add it to the scorecard. + +To modify any portion of an existing checkpoint, simply make whatever change is necessary to the checkpoint - changes are automatically saved and there is no need for a submit button. + + +STEP 4. Applying QC settings +Once status templates and scorecards are defined, they can be applied to campaigns, lists, and ingroups via the "QC Statuses" and "QC scorecards" settings in each, which will only appear if the QC feature is enabled through the system setting in step 1. For campaigns, you must view the campaign settings in "Detail" view mode, and use the "QC" link that appears in the upper right. For lists and ingroups, the QC settings appear among their other settings. In the event of conflicting settings, the order of priority is ingroup -> list -> campaign. + + +STEP 5. Claiming calls +Under the new QC system, quality control is done on a per-call basis, meaning leads that may not currently have a status covered by a QC template can still be reviewed if a past call was dispositioned with a status covered by a QC_TEMPLATE settings container that was applied to a campaign/list/ingroup the call belongs to. + +Calls can be claimed and evaluated via three links under the "Quality Control" menu in the Admin - "QC Calls by Campaign", "QC Calls by List", and "QC Calls by Ingroup". Clicking on one of these links will show any QC-enabled campaign/list/ingroup that is currently active along with a list of the current QC-eligible statuses assigned to it and the number of qualifying calls currently in the system available to be claimed (this count is affected not only by the statuses assigned, but also the expiration days set in the System Settings). Additionally, the user group's QC settings will filter out any campaign/list/ingroup the user is not allowed to view. For lists, the filtering is done using the list's current campaign against the list of allowed QC campaigns per the user group settings. + +When you claim a call, the dialer will assign the most appropriate scorecard for the lead at the time the lead is claimed. This means if the same call would appear on different claim lists in the admin, the dialer will assign the scorecard associated with the higher-priority element (ingroup -> list -> campaign) regardless of which "QC calls" section it's claimed from. For example, if a campaign shows a call to a lead as being eligible for being claimed based on the campaign QC settings, and the same call meets the QC settings assigned to a list, the scorecard for the list will be assigned to the QC session even if it is claimed from the "QC Calls by Campaign" page. + +Clicking on a record here will take you to a page that will display any calls you currently have claimed and unfinished, and if you have fewer claimed calls than the "QC Claim Limit" system setting, all the available calls under the campaign/list/ingroup will be shown grouped by status and ordered by call date. Each record displays the lead ID, name on the lead, date of the call, and the agent who made the call. Clicking on the lead ID, name, or call date will "claim" the call and take you to the quality control interface to evaluate the call. + + +STEP 6. Using the QC display screen +Across the top of the screen, the page will print which campaign, ingroup, or list the call fits under per your dialer's settings. The QC display screen consists of four sections, of which one can be displayed at any time and can be toggled via the buttons across the top of the screen. + +The section you see by default contains the scorecard. The header of each scorecard displays the scorecard ID and also the recording ID for that particular call. The recording ID is matched via the uniqueid from the vicidial_agent_log table to the vicidial_id in the recording_log table. If there is no matching recording, then the default recording becomes the one in the recording log that is closest to the date and time of the call. Beneath the header each active checkpoint is displayed in the order designated by the scorecard's settings. This is where each checkpoint's score can be entered, along with any comments regarding said checkpoint. Scores and comments are automatically saved when they are entered. Beneath the checkpoints is the link to play the recording for the call. Underneath that are the available statuses that quality control can apply to the call when the evaluation is completed, with a button to FINISH the call. Clicking this will mark the call as finished and take you back to the Quality Control section in the admin. Alternatively, there is a red "RELEASE" button. This is clicked when the call needs to be placed back into the quality control queue. It relinquishes ownership of the call and purges any scorecard data pertaining to the call. This can be used to re-claim the call, which can be useful if the scorecard for the call has been modified since the call was originally claimed. Finally in this section, a list of all recordings made for this lead are displayed below the scorecard and can be listened to here, in the event another phone call needs to be checked in order to finish the scorecard. + +The second section is for lead information, where the agent can view the lead information for the called lead in the standard vicidial_list fields. Additionally, if a QC webform was defined for the campaign, list, or ingroup under which the lead is being evaluated, the link to the webform will appear here as well. If custom fields are defined for the lead, those will appear within a frame at the bottom of the screen. Like with the scorecards, modifying the standard lead information will cause it to be automatically updated in the vicidial_list table. Custom lead information still requires use of a submit button. + +The third section pertains to callbacks for the lead. If you are currently logged into the agent interface in a separate window, you can be given the option to dial the lead from here by clicking on the "Dial lead" link within the frame that appears at the top of the section. Additionally, if you dial the lead and make changes to the customer information within the agent interface, the QC interface will also auto-update to match what you entered once you disposition the call. + +Below the callback frame, any current callbacks for this lead are displayed. These can be modified to change ownership to a specific user or to "ANYONE", and also the call date and time can be modified. + +The final section is the log section - this is a read-only section where you can view the quality control logs pertaining to the call being evaluated. The log records will show date and time, status changes to the call (if any), who viewed the call, and also if lead information is changed on a specific log record, that log records will show the word "DETAILS" on the right and you can see specifically what was changed if you hover your mouse over that word. + +Beneath that are the "common" log records, showing calls to this lead (outbound), closer records for this lead (inbound), and agent log records. + + +STEP 7. Quality Control Report +This report shows quality control call activity within user-selected parameters. If displayed as HTML, it will output each individual call with a header row that shows things like the call date, agent, campaign, call status, QC scorecard and QC result. Underneath that, each checkpoint in the scorecard applied to call will be displayed as individual rows with scores and comments per checkpoint. The report can also be downloaded as a CSV where each call will be a row in the resulting file with the checkpoint data appended to each row. + +Report parameters are: + - CALL DATE - The date range in which the call was originally made. + - FINISH DATE - The date range in which the QC agent who evaluated the call marked it as finished. This will automatically filter out unfinished calls if this is used, regardless of what QC statuses (see below) are selected. + - CAMPAIGNS - The campaign the original call was made under. + - QC STATUS - The current status of the call in the quality control system - this is NOT the call status from dialing. + - USERS - The agent(s) who placed the original calls. + - QC AGENTS - The agents who evaluated the call in the quality control system. + - SHOW %'s - If this box is checked, the scores given by the QC agents will be displayed as percentages instead of points. + - SEARCH ARCHIVED DATA - If this is checked, the archived quality control log tables will be searched if they exist. + + + + + + + + + + + + + +-------------------------------------------------------------------------------- + PREVIOUS VERSIONS +-------------------------------------------------------------------------------- Thanks to the Pound Team(pounteam.com) and Affinity On-Call(affinity.co.za) for contributing this functionaly QC application to the vicidial project. @@ -167,283 +282,3 @@ Note for developers: All information for the viewed and modified records is stor Notes Testing: “QC Only” user modeled after “Reporting Only” user. Requires user level > 1, active = “Y”, and QC Enabled. To QC Modify a lead that is NOT presently a QC status (whether it was in the past or not), search for and Modify the lead (under Lists->Search for a Lead), then click on “Click here to QC Modify this lead” at the bottom of the Admin Modify Lead screen (if you have QC permissions, this will be visible). - - - - - - - - - - - - - - - - - - - - - -******************** ARCHIVED DOC BELOW, NOT APPLICABLE ********************************************** - -******************** PLEASE IGNORE FURTHER CONTENT, IT WILL BE DELETED IN A FUTURE REVISION ********** - - -** THIS QC FUNCTIONALITY PROSESS IS PLANNED FOR THE 2.0.5 RELEASE AND IS CURRENTLY IN DEVELOPMENT ** - -This will outline the process I have thought through for adding a Quality Assurance(QA) or Quality Control(QC) process to the VICIDIAL system. As the needs have changed for sponsor client and VICIDIAL has evolved since this functionality was first put into the planning stages, there have been several changes to how the QC process is going to be built. The objective is to add the following QC features to make VICIDIAL a more well-rounded product: -- ability to define which statuses are to be able to be QCd per campaign and inbound group(queue) -- ability to give agents permission to QC records for their allowable campaigns/inbound groups -- ability to log all access and changes to QCd records -- creation of some basic reports on QC activity - - - -The back-end process will work like this: -- ADMIN_keepalive_ALL.pl script will look for the 'Q' in the keepalive definition in /etc/astguiclient.conf file. If it is set, it will trigger a script (QC_gather_records.pl) to gather the QC records every five minutes(with a 15 second delay) since the last QC gathering as defined in the system_settings table qc_last_pull_time field(which is populated with four-hours-before the START time of the last QC-pull run to make sure to catch all potential long calls that may have ended). The time interval for this might be made configurable. -- There will also be an optional method of pulling QC records available to the QC managers that enables them to specify a date range to pull and insert records -- Selected records from the vicidial_list table (keyed on the the vicidial_log and vicidial_closer_log tables) will be taken and inserted into the vicidial_qc_list table. -- QC agents are then able to run their process starting with the earliest records for their selected campaign/inbound groups -- After QC agents have PASSed, FINISHed and COMMITted the QC records, then they can be exported - - - -Agent-side scripts: - - qc.php - the screen that agents log in to - - qc_query.php - the data processing script that handles most of the AJAX queries and IFRAME displays from qc.php - - -The QC agent will login to the new qc.php screen within the agc web directory. They will then have a screen very similar to the vicidial.php login screen(but in a different color) that will have a user/pass to fill in. Then when they login the QC agents with level of 1-3 will see a green screen similar to the vicidial.php inbound(CLOSER-type) screen that will show them their allowable qc inbound-groups and campaigns. The agent will then choose which in-groups and campaigns that they want to QC the records for and then they will submit and they will be logged-in to the QC system. QC agents with a qc_level of 4-5 can select to review first level reccords, review all 2nd level records, review only 2nd level changed-status or review 2nd level same-status records. QC agents with 6-7 qc_level can also have the option of entering a management screen showing more information on the QC system including committing QC records and links to QC reports. - -Upon login, they will be able to see the count of QC-able records and they can click on a link to bring up the next record to be QCd. - -Upon clicking on a link, the qc.php application will insert a record into the vicidial_qc_log to keep track of changes and other information on the qc record session. The customer and original call data will remain unaltered in the vicidial_qc_list table. - -The SCRIPTS tab and web form will both function exactly as they do in the vicidial.php application, with the exception that there will be added qc_web_form_address and qc_script options for both campaigns and inbound groups. There will also be an option to have any of these launched upon a new record appearing on the QC agent's screen. - -The qc.php user interface will be using AJAX as a method to bring up records and keep track of QC-agent activity and performance. - -An optional element is for a small audio frame be opened with each new customer record that will have an audio recording of the call that the QC agent can listen to. At this point in time, the best candidate for this is the Flourish Flash-based application(http://flourishplayer.sourceforge.net/) It is open source under a BSD-like license and is based on Adobe Flash, which currently seems to be much more lightweight and provides a much lower barrier to entry on most platforms than JAVA does. - - - -Each qc_user_level will have different permissions for the qc system: -1- modify nothing -2- modify nothing but status -3- modify everything -4- can check records of other QC agents -5- can view stats on qc system and unlock locked records from first level QC agents -6- can view finished and non-committed records and alter them and unlock locked records from first and second level QC agents -7- Manager level (can do anything including delete QC records) - -The the QC agent roles: -FIRST - first level review -SECOND_ALL - second level review all records -SECOND_CHANGED - second level review only changed-status records -SECOND_PASSED - second level review only unchanged-status records -THIRD - third level review and commit/clear -MANAGER - manager level actions - -The qc_stage is a record status within QC that tells what is going on with the record: -NEW - record has never been QCd -LOCK_1 - a QC agent is reviewing the record -PASS - QC agent has passed the record -LOCK_2 - a QC agent is reviewing the record for possible finishing -FINISH - record is ready to be processed -COMMIT - QC record is committed to the system and cannot be modified by anyone -DEAD - QC record is old and present for logs only, newer record has taken it's place - - -The Database Changes: -!!! IMPORTANT !!! -THESE ARE FOR REFERENCE ONLY, DO NOT RUN THEM!!! - -# This table contains the live session information for qc_agents - CREATE TABLE qc_agent_sessions ( -qc_session_id INT(9) UNSIGNED PRIMARY KEY NOT NULL, -user VARCHAR(20), -qc_user_level INT(2) default '0', -qc_role VARCHAR(20), -status ENUM('READY','INQC','PAUSED') default 'PAUSED', -qc_id INT(9) UNSIGNED NOT NULL, -lead_id INT(9) UNSIGNED NOT NULL, -selected_campaigns_groups TEXT, -qc_records_today SMALLINT(5) UNSIGNED default '0', -login_time DATETIME, -last_action_time DATETIME, -index (user), -index (last_action_time) -); - -# This table contains the stats information for qc_agents for today - CREATE TABLE qc_agent_stats ( -user VARCHAR(20), -campaign_group_id VARCHAR(20), -qc_records_today SMALLINT(5) UNSIGNED default '0', -last_record_time DATETIME, -last_record_finish DATETIME, -index (user), -index (campaign_group_id) -); - -# This table contains the log information for qc_agent logins -CREATE TABLE vicidial_user_qc_log ( -user VARCHAR(20), -event_date DATETIME, -selected_campaigns_groups TEXT, -index (user), -index (event_date) -); - -# For ability to restrict statuses by user_level per campaign/in-group - CREATE TABLE qc_allowed_statuses ( -status VARCHAR(6) PRIMARY KEY NOT NULL, -qc_user_level INT(2) default '0', -campaign_group_id VARCHAR(20) -); - -# This table contains the original lead and log information before changes - CREATE TABLE vicidial_qc_list ( -qc_id INT(9) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL, -qc_import_date DATETIME, -qc_stage VARCHAR(6) default 'NEW', -call_date DATETIME, -vicidial_id VARCHAR(20) UNIQUE NOT NULL, -campaign_group_id VARCHAR(20), -lead_id INT(9) UNSIGNED NOT NULL, -list_id BIGINT(14) UNSIGNED, -length_in_sec SMALLINT(5) UNSIGNED default '0', -status VARCHAR(6), -call_type VARCHAR(20), -term_reason ENUM('CALLER','AGENT','QUEUETIMEOUT','ABANDON','AFTERHOURS','NONE') default 'NONE', -modify_date TIMESTAMP, -qc_user VARCHAR(20), -user VARCHAR(20), -user_group VARCHAR(20), -fronter VARCHAR(20), -vendor_lead_code VARCHAR(20), -source_id VARCHAR(50), -phone_code VARCHAR(10), -phone_number VARCHAR(12), -title VARCHAR(4), -first_name VARCHAR(30), -middle_initial VARCHAR(1), -last_name VARCHAR(30), -address1 VARCHAR(100), -address2 VARCHAR(100), -address3 VARCHAR(100), -city VARCHAR(50), -state VARCHAR(2), -province VARCHAR(50), -postal_code VARCHAR(10), -country_code VARCHAR(3), -gender ENUM('M','F','U') default 'U', -date_of_birth DATE, -alt_phone VARCHAR(12), -email VARCHAR(70), -security_phrase VARCHAR(100), -comments VARCHAR(255), -index (vicidial_id), -index (lead_id), -index (phone_number) -); - -# This table contains the updated QC records - CREATE TABLE vicidial_qc_log ( -qc_log_id INT(9) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL, -qc_id INT(9) UNSIGNED NOT NULL, -qc_stage VARCHAR(6), -modify_date TIMESTAMP, -qc_user VARCHAR(20), -qc_status VARCHAR(6), -qc_code VARCHAR(8), -qc_date DATETIME, -qc_length_in_sec SMALLINT(5) UNSIGNED default '0', -qc_comments TEXT, -qc_altered ENUM('0','1') default '0', -status VARCHAR(6), -vendor_lead_code VARCHAR(20), -phone_code VARCHAR(10), -phone_number VARCHAR(12), -title VARCHAR(4), -first_name VARCHAR(30), -middle_initial VARCHAR(1), -last_name VARCHAR(30), -address1 VARCHAR(100), -address2 VARCHAR(100), -address3 VARCHAR(100), -city VARCHAR(50), -state VARCHAR(2), -province VARCHAR(50), -postal_code VARCHAR(10), -country_code VARCHAR(3), -gender ENUM('M','F','U') default 'U', -date_of_birth DATE, -alt_phone VARCHAR(12), -email VARCHAR(70), -security_phrase VARCHAR(100), -comments VARCHAR(255), -index (qc_id), -index (phone_number), -index (qc_stage) -); - - - - - - - - - -# Changes committed to upgrade sql file: - -# For the inbound groups table, some fields will need to be added to the vicidial_campaigns table: -ALTER TABLE vicidial_inbound_groups ADD qc_enabled ENUM('Y','N') default 'N'; -ALTER TABLE vicidial_inbound_groups ADD qc_statuses TEXT; -ALTER TABLE vicidial_inbound_groups ADD qc_shift_id VARCHAR(20) default '24HRMIDNIGHT'; -ALTER TABLE vicidial_inbound_groups ADD qc_get_record_launch ENUM('NONE','SCRIPT','WEBFORM','QCSCRIPT','QCWEBFORM') default 'NONE'; -ALTER TABLE vicidial_inbound_groups ADD qc_show_recording ENUM('Y','N') default 'Y'; -ALTER TABLE vicidial_inbound_groups ADD qc_web_form_address VARCHAR(255); -ALTER TABLE vicidial_inbound_groups ADD qc_script VARCHAR(10); - -# Alter some earlier defined fields and populate with default values -ALTER TABLE vicidial_campaigns CHANGE campaign_shift_start_time qc_shift_id VARCHAR(20) default '24HRMIDNIGHT'; -ALTER TABLE vicidial_campaigns CHANGE campaign_shift_length qc_get_record_launch ENUM('NONE','SCRIPT','WEBFORM','QCSCRIPT','QCWEBFORM') default 'NONE'; -ALTER TABLE vicidial_campaigns CHANGE campaign_day_start_time qc_show_recording ENUM('Y','N') default 'Y'; -UPDATE vicidial_campaigns SET qc_shift_id='24HRMIDNIGHT'; -UPDATE vicidial_campaigns SET qc_get_record_launch='NONE'; -UPDATE vicidial_campaigns SET qc_show_recording='Y'; - -ALTER TABLE system_settings ADD qc_last_pull_time DATETIME; - -# qc codes to be used for statistics - CREATE TABLE vicidial_qc_codes ( -code VARCHAR(8) PRIMARY KEY NOT NULL, -code_name VARCHAR(30) -); - -# For the campaigns table, some fields will need to be added to the vicidial_campaigns table: -ALTER TABLE vicidial_campaigns ADD qc_enabled ENUM('Y','N') default 'N'; -ALTER TABLE vicidial_campaigns ADD qc_statuses TEXT; -ALTER TABLE vicidial_campaigns ADD qc_lists TEXT; -ALTER TABLE vicidial_campaigns ADD campaign_shift_start_time VARCHAR(4) default '0900'; -ALTER TABLE vicidial_campaigns ADD campaign_shift_length VARCHAR(5) default '16:00'; -ALTER TABLE vicidial_campaigns ADD campaign_day_start_time VARCHAR(4) default '0100'; -ALTER TABLE vicidial_campaigns ADD qc_web_form_address VARCHAR(255); -ALTER TABLE vicidial_campaigns ADD qc_script VARCHAR(10); - -# For the in-groups/campaigns QC permissions, some fields will need to be added to the vicidial_user_groups table: -ALTER TABLE vicidial_user_groups ADD qc_allowed_campaigns TEXT; -ALTER TABLE vicidial_user_groups ADD qc_allowed_inbound_groups TEXT; - -# For the user QC permissions, some fields will need to be added to the vicidial_users table: -ALTER TABLE vicidial_users ADD qc_enabled ENUM('1','0') default '0'; -ALTER TABLE vicidial_users ADD qc_user_level INT(2) default '1'; -ALTER TABLE vicidial_users ADD qc_pass ENUM('1','0') default '0'; -ALTER TABLE vicidial_users ADD qc_finish ENUM('1','0') default '0'; -ALTER TABLE vicidial_users ADD qc_commit ENUM('1','0') default '0'; 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 0d97cde9..f39fe350 100644 --- a/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql +++ b/agc_2-X/trunk/extras/MySQL_AST_CREATE_tables.sql @@ -1054,7 +1054,9 @@ daily_call_count_limit TINYINT(3) UNSIGNED default '0', daily_limit_manual VARCHAR(20) default 'DISABLED', transfer_button_launch VARCHAR(12) default 'NONE', shared_dial_rank TINYINT(3) default '99', -agent_search_method VARCHAR(2) default '' +agent_search_method VARCHAR(2) default '', +qc_scorecard_id VARCHAR(20) DEFAULT '', +qc_statuses_id VARCHAR(20) DEFAULT '' ) ENGINE=MyISAM; CREATE TABLE vicidial_lists ( @@ -1095,7 +1097,10 @@ cache_count_new INT(9) UNSIGNED default '0', cache_count_dialable_new INT(9) UNSIGNED default '0', cache_date DATETIME, inbound_drop_voicemail VARCHAR(20), -inbound_after_hours_voicemail VARCHAR(20) +inbound_after_hours_voicemail VARCHAR(20), +qc_scorecard_id VARCHAR(20) DEFAULT '', +qc_statuses_id VARCHAR(20) DEFAULT '', +qc_web_form_address VARCHAR(255) DEFAULT '' ) ENGINE=MyISAM; CREATE TABLE vicidial_statuses ( @@ -1347,7 +1352,9 @@ browser_alert_sound VARCHAR(20) default '---NONE---', browser_alert_volume TINYINT(3) UNSIGNED default '50', answer_signal ENUM('START','ROUTE','NONE') DEFAULT 'START', no_agent_delay SMALLINT(5) default '0', -agent_search_method VARCHAR(2) default '' +agent_search_method VARCHAR(2) default '', +qc_scorecard_id VARCHAR(20) DEFAULT '', +qc_statuses_id VARCHAR(20) DEFAULT '' ) ENGINE=MyISAM; CREATE TABLE vicidial_stations ( @@ -1885,7 +1892,9 @@ manual_dial_phone_strip VARCHAR(10) default 'DISABLED', daily_call_count_limit ENUM('0','1') default '0', allow_shared_dial ENUM('0','1','2','3','4','5','6') default '0', agent_search_method ENUM('0','1','2','3','4','5','6') default '0', -phone_defaults_container VARCHAR(40) default '---DISABLED---' +phone_defaults_container VARCHAR(40) default '---DISABLED---', +qc_claim_limit TINYINT UNSIGNED DEFAULT '3', +qc_expire_days TINYINT UNSIGNED DEFAULT '3' ) ENGINE=MyISAM; CREATE TABLE vicidial_campaigns_list_mix ( @@ -4412,6 +4421,80 @@ index (call_time), index (drop_time) ) ENGINE=MyISAM; +CREATE TABLE quality_control_checkpoint_log ( +qc_checkpoint_log_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, +qc_log_id INT(10) UNSIGNED DEFAULT NULL, +campaign_id VARCHAR(8) DEFAULT NULL, +group_id VARCHAR(20) DEFAULT NULL, +list_id BIGINT(14) UNSIGNED DEFAULT NULL, +qc_scorecard_id VARCHAR(20) DEFAULT NULL, +checkpoint_row_id INT(10) UNSIGNED DEFAULT NULL, +checkpoint_text TEXT, +checkpoint_rank TINYINT(3) UNSIGNED DEFAULT NULL, +checkpoint_points TINYINT(3) UNSIGNED DEFAULT NULL, +instant_fail ENUM('Y','N') DEFAULT 'N', +checkpoint_points_earned TINYINT(5) UNSIGNED DEFAULT NULL, +qc_agent VARCHAR(20) DEFAULT NULL, +checkpoint_comment_agent TEXT, +PRIMARY KEY (qc_checkpoint_log_id) +) ENGINE=MyISAM; + +CREATE TABLE quality_control_checkpoints ( +checkpoint_row_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, +qc_scorecard_id VARCHAR(20) DEFAULT NULL, +checkpoint_text TEXT, +checkpoint_rank INT(3) UNSIGNED DEFAULT NULL, +checkpoint_points TINYINT(3) UNSIGNED DEFAULT NULL, +instant_fail ENUM('Y','N') DEFAULT 'N', +admin_notes TEXT, +active ENUM('Y','N') DEFAULT NULL, +campaign_ids TEXT, +ingroups TEXT, +list_ids TEXT, +create_date DATETIME DEFAULT NULL, +create_user VARCHAR(10) DEFAULT NULL, +modify_date TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), +modify_user VARCHAR(10) DEFAULT NULL, +PRIMARY KEY (checkpoint_row_id) +) ENGINE=MyISAM; + +CREATE TABLE quality_control_queue ( +qc_log_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, +qc_display_method ENUM('CALL','LEAD') DEFAULT 'CALL', +lead_id INT(10) UNSIGNED DEFAULT NULL, +status VARCHAR(6) DEFAULT NULL, +call_date DATETIME DEFAULT NULL, +agent_log_id INT(9) UNSIGNED DEFAULT NULL, +user VARCHAR(20) DEFAULT NULL, +user_group VARCHAR(20) DEFAULT NULL, +campaign_id VARCHAR(8) DEFAULT NULL, +group_id VARCHAR(20) DEFAULT NULL, +list_id BIGINT(14) UNSIGNED DEFAULT NULL, +scorecard_source ENUM('CAMPAIGN','INGROUP','LIST') DEFAULT 'CAMPAIGN', +qc_web_form_address VARCHAR(255) DEFAULT NULL, +vicidial_id VARCHAR(20) DEFAULT NULL, +recording_id INT(10) UNSIGNED DEFAULT NULL, +qc_scorecard_id VARCHAR(20) DEFAULT NULL, +qc_agent VARCHAR(20) DEFAULT NULL, +qc_user_group VARCHAR(20) DEFAULT NULL, +qc_status VARCHAR(20) DEFAULT NULL, +date_modified TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), +date_claimed DATETIME DEFAULT NULL, +date_completed DATETIME DEFAULT NULL, +PRIMARY KEY (qc_log_id), +UNIQUE KEY quality_control_queue_agent_log_id_key (agent_log_id), +KEY quality_control_queue_lead_id_key (lead_id) +) ENGINE=MyISAM; + +CREATE TABLE quality_control_scorecards ( +qc_scorecard_id VARCHAR(20) NOT NULL, +scorecard_name VARCHAR(255) DEFAULT NULL, +active ENUM('Y','N') DEFAULT 'Y', +passing_score SMALLINT(5) UNSIGNED DEFAULT 0, +last_modified TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), +PRIMARY KEY (qc_scorecard_id) +) ENGINE=MyISAM; + ALTER TABLE vicidial_email_list MODIFY message text character set utf8; @@ -4741,9 +4824,9 @@ INSERT INTO vicidial_settings_containers(container_id,container_notes,container_ INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('TIMEZONES_CANADA','Canadian Timezone List','TIMEZONE_LIST','---ALL---','CAN,NST,Y,Newfoundland Time Zone\nCAN,AST,Y,Atlantic Time Zone\nCAN,EST,Y,Eastern Time Zone\nCAN,CST,Y,Central Time Zone\nCAN,CST,N,Saskatchewan Time Zone\nCAN,MST,Y,Mountain Time Zone\nCAN,PST,Y,Pacific Time Zone\n'); INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('TIMEZONES_AUSTRALIA','Australian Timezone List','TIMEZONE_LIST','---ALL---','AUS,AEST,Y,Eastern Australia Time Zone\nAUS,AEST,N,Queensland Time Zone\nAUS,ACST,Y,Central Australia Time Zone\nAUS,ACST,N,Northern Territory Time Zone\nAUS,AWST,N,Western Australia Time Zone\n'); INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('PHONE_DEFAULTS','Default phone settings for preloading','PHONE_DEFAULTS','---ALL---','# Below are all phone settings recognized under the PHONE_DEFAULTS \r\n# container type and the type of data each accepts. Any setting that\r\n# uses a default value in the database has said value pre-set below\r\n\r\n# 10 char max\r\nvoicemail_id => \r\n \r\n# 15 char max\r\nserver_ip => \r\n\r\n# 100 char max\r\npass => \r\n\r\n# 10 char max\r\nstatus => \r\n\r\n# Y/N only\r\nactive => Y\r\n\r\n# 50 char max\r\nphone_type => \r\n\r\n# \'SIP\',\'Zap\',\'IAX2\' or \'EXTERNAL\'\r\nprotocol => SIP\r\n\r\n# positive or negatier 2-decimal floating point number\r\nlocal_gmt => -5.00\r\n\r\n# 20 char max\r\nvoicemail_dump_exten => 85026666666666\r\n\r\n# 20 char max\r\noutbound_cid => \r\n\r\n# 100 char max\r\nemail => \r\n\r\n# 15 char max\r\ntemplate_id => \r\n\r\n# text, conf_override can span multiple lines, see below\r\nconf_override => \r\n# type=friend\r\n# host=dynamic\r\n# canreinvite=no\r\n# context=default1\r\n\r\n# 50 char max\r\nphone_context => default\r\n\r\n# Unsigned - max value 65536\r\nphone_ring_timeout => 60\r\n\r\n# 20 char max\r\nconf_secret => test\r\n\r\n# Y/N only\r\ndelete_vm_after_email => N\r\n\r\n# Options - Y, N, or Y_API_LAUNCH\r\nis_webphone => N\r\n\r\n# Y/N only\r\nuse_external_server_ip => N\r\n\r\n# 100 char max\r\ncodecs_list => \r\n\r\n# 0/1 only\r\ncodecs_with_template => 0\r\n\r\n# Options - Y, N, TOGGLE, or TOGGLE_OFF\r\nwebphone_dialpad => Y\r\n\r\n# Y/N only\r\non_hook_agent => N\r\n\r\n# Y/N only\r\nwebphone_auto_answer => Y\r\n\r\n# 30 char max\r\nvoicemail_timezone => eastern\r\n\r\n# 255 char max\r\nvoicemail_options => \r\n\r\n# 20 char max\r\nuser_group => ---ALL---\r\n\r\n# 100 char max\r\nvoicemail_greeting => \r\n\r\n# 20 char max\r\nvoicemail_dump_exten_no_inst => 85026666666667\r\n\r\n# Y/N only\r\nvoicemail_instructions => Y\r\n\r\n# Y/N only\r\non_login_report => N\r\n\r\n# 40 char max\r\nunavail_dialplan_fwd_exten => \r\n\r\n# 100 char max\r\nunavail_dialplan_fwd_context => \r\n\r\n# text\r\nnva_call_url => \r\n\r\n# 40 char max\r\nnva_search_method => \r\n\r\n# 255 char max\r\nnva_error_filename => \r\n\r\n# Integer, any size\r\nnva_new_list_id => 995\r\n\r\n# 10 char max\r\nnva_new_phone_code => 1\r\n\r\n# 6 char max\r\nnva_new_status => NVAINS\r\n\r\n# Y/N only\r\nwebphone_dialbox => Y\r\n\r\n# Y/N only\r\nwebphone_mute => Y\r\n\r\n# Y/N only\r\nwebphone_volume => Y\r\n\r\n# Y/N only\r\nwebphone_debug => N\r\n\r\n# 20 char max\r\noutbound_alt_cid => \r\n\r\n# Y/N only\r\nconf_qualify => Y\r\n\r\n# 255 char max\r\nwebphone_layout => \r\n'); - -INSERT INTO vicidial_settings_containers VALUES ('INTERNATIONAL_DNC_IMPORT','Process DNC lists of various countries from FTP site','PERL_CLI','---ALL---','# This setting container is used for the international DNC system. \r\n# The below two settings are mandatory for importing suppression lists\r\n# and tell the import process where to look for new files and where to\r\n# move them when handled. These settings cannot have the same value. \r\n--file-dir=/root/ftp\r\n--file-destination=/root/ftp/DONE\r\n\r\n# Uncomment below and set the status to whatever custom disposition you \r\n# would like already-loaded leads to be set to when they dedupe against\r\n# a country\'s DNC list (default is \"DNCI\")\r\n# --dnc-status-override=BMNR\r\n\r\n# The below settings are optional for when files are stored on a remote\r\n# server. It is strongly recommended these settings are not used and\r\n# that the processing scripts and files are stored locally on the same\r\n# server. \r\n# --ftp-host=localhost\r\n# --ftp-user=user\r\n# --ftp-pwd=pwd\r\n# --ftp-port=21\r\n# --ftp-passive=1\r\n'),('DNC_IMPORT_FORMATS','Import formats for DNC files','OTHER','---ALL---','# This setting container is used for storing file formats used when \r\n# loading DNC suppression lists into the dialer. \r\n#\r\n# import template => (delimited|fixed),delimiter,phone1(,phone2,phone3)\r\n#\r\n# For delimited files, the phone1 value should be the index value of\r\n# the field where the phone appears. The first array index is 0 and\r\n# indexes continue through the natural numbers.\r\n\r\n# In delimited files, acceptable values for the \"delimiter\" field are:\r\n# - \"tab\", \"pipe\", \"comma\", \"quote-comma\"\r\nBASIC_DELIMITED_FORMAT => delimited,pipe,0\r\n\r\n# If the phone number is split into multiple fields (ex: area code in\r\n# one field, rest of the number in another), simply list additional \r\n# indices of the phone number fields separated by commas in the order \r\n# in which the data should be combined to make the complete phone \r\n# number \r\nDELIMITED_WITH_AC_AND_EXCHANGE_SPLIT => delimited,tab,0,1\r\n\r\n# For fixed-length files, the phone field values should be of the type:\r\n# - \"starting_position|length\"\r\nBASIC_FIXED_FORMAT => fixed,,0|10\r\n\r\n# (delimited|fixed) is not used for CSV/Excel files, so all that needs \r\n# providing for those is the index field value(s) of the phone number\r\nBASIC_CSV_OR_EXCEL_FORMAT => ,,0'),('DNC_CURRENT_BLOCKED_LISTS','Lists currently blocked due to pending DNC scrub','READ_ONLY','---ALL---',''); +INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('QC_STATUS_TEMPLATE','Sample QC Status Template','QC_TEMPLATE','---ALL---','# These types of containers are simply used for creating a list of \r\n# QC-enabled statuses to apply to campaigns, lists, and ingroups.\r\n# Simply put all the statuses that this template should allow in\r\n# a comma-delimited string, as below:\r\n\r\nSALE,DNC,NI'); +INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('INTERNATIONAL_DNC_IMPORT','Process DNC lists of various countries from FTP site','PERL_CLI','---ALL---','# This setting container is used for the international DNC system. \r\n# The below two settings are mandatory for importing suppression lists\r\n# and tell the import process where to look for new files and where to\r\n# move them when handled. These settings cannot have the same value. \r\n--file-dir=/root/ftp\r\n--file-destination=/root/ftp/DONE\r\n\r\n# Uncomment below and set the status to whatever custom disposition you \r\n# would like already-loaded leads to be set to when they dedupe against\r\n# a country\'s DNC list (default is \"DNCI\")\r\n# --dnc-status-override=BMNR\r\n\r\n# The below settings are optional for when files are stored on a remote\r\n# server. It is strongly recommended these settings are not used and\r\n# that the processing scripts and files are stored locally on the same\r\n# server. \r\n# --ftp-host=localhost\r\n# --ftp-user=user\r\n# --ftp-pwd=pwd\r\n# --ftp-port=21\r\n# --ftp-passive=1\r\n'),('DNC_IMPORT_FORMATS','Import formats for DNC files','OTHER','---ALL---','# This setting container is used for storing file formats used when \r\n# loading DNC suppression lists into the dialer. \r\n#\r\n# import template => (delimited|fixed),delimiter,phone1(,phone2,phone3)\r\n#\r\n# For delimited files, the phone1 value should be the index value of\r\n# the field where the phone appears. The first array index is 0 and\r\n# indexes continue through the natural numbers.\r\n\r\n# In delimited files, acceptable values for the \"delimiter\" field are:\r\n# - \"tab\", \"pipe\", \"comma\", \"quote-comma\"\r\nBASIC_DELIMITED_FORMAT => delimited,pipe,0\r\n\r\n# If the phone number is split into multiple fields (ex: area code in\r\n# one field, rest of the number in another), simply list additional \r\n# indices of the phone number fields separated by commas in the order \r\n# in which the data should be combined to make the complete phone \r\n# number \r\nDELIMITED_WITH_AC_AND_EXCHANGE_SPLIT => delimited,tab,0,1\r\n\r\n# For fixed-length files, the phone field values should be of the type:\r\n# - \"starting_position|length\"\r\nBASIC_FIXED_FORMAT => fixed,,0|10\r\n\r\n# (delimited|fixed) is not used for CSV/Excel files, so all that needs \r\n# providing for those is the index field value(s) of the phone number\r\nBASIC_CSV_OR_EXCEL_FORMAT => ,,0'),('DNC_CURRENT_BLOCKED_LISTS','Lists currently blocked due to pending DNC scrub','READ_ONLY','---ALL---',''); UPDATE system_settings set vdc_agent_api_active='1'; -UPDATE system_settings SET db_schema_version='1618',db_schema_update_date=NOW(),reload_timestamp=NOW(); +UPDATE system_settings SET db_schema_version='1619',db_schema_update_date=NOW(),reload_timestamp=NOW(); diff --git a/agc_2-X/trunk/extras/upgrade_2.14.sql b/agc_2-X/trunk/extras/upgrade_2.14.sql index 226fe07f..cea042d8 100644 --- a/agc_2-X/trunk/extras/upgrade_2.14.sql +++ b/agc_2-X/trunk/extras/upgrade_2.14.sql @@ -1440,3 +1440,94 @@ INSERT INTO vicidial_settings_containers VALUES ('PHONE_DEFAULTS','Default phone ALTER TABLE system_settings ADD phone_defaults_container VARCHAR(40) default '---DISABLED---'; UPDATE system_settings SET db_schema_version='1618',db_schema_update_date=NOW() where db_schema_version < 1618; + +CREATE TABLE quality_control_checkpoint_log ( +qc_checkpoint_log_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, +qc_log_id INT(10) UNSIGNED DEFAULT NULL, +campaign_id VARCHAR(8) DEFAULT NULL, +group_id VARCHAR(20) DEFAULT NULL, +list_id BIGINT(14) UNSIGNED DEFAULT NULL, +qc_scorecard_id VARCHAR(20) DEFAULT NULL, +checkpoint_row_id INT(10) UNSIGNED DEFAULT NULL, +checkpoint_text TEXT, +checkpoint_rank TINYINT(3) UNSIGNED DEFAULT NULL, +checkpoint_points TINYINT(3) UNSIGNED DEFAULT NULL, +instant_fail ENUM('Y','N') DEFAULT 'N', +checkpoint_points_earned TINYINT(5) UNSIGNED DEFAULT NULL, +qc_agent VARCHAR(20) DEFAULT NULL, +checkpoint_comment_agent TEXT, +PRIMARY KEY (qc_checkpoint_log_id) +) ENGINE=MyISAM; + +CREATE TABLE quality_control_checkpoints ( +checkpoint_row_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, +qc_scorecard_id VARCHAR(20) DEFAULT NULL, +checkpoint_text TEXT, +checkpoint_rank INT(3) UNSIGNED DEFAULT NULL, +checkpoint_points TINYINT(3) UNSIGNED DEFAULT NULL, +instant_fail ENUM('Y','N') DEFAULT 'N', +admin_notes TEXT, +active ENUM('Y','N') DEFAULT NULL, +campaign_ids TEXT, +ingroups TEXT, +list_ids TEXT, +create_date DATETIME DEFAULT NULL, +create_user VARCHAR(10) DEFAULT NULL, +modify_date TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), +modify_user VARCHAR(10) DEFAULT NULL, +PRIMARY KEY (checkpoint_row_id) +) ENGINE=MyISAM; + +CREATE TABLE quality_control_queue ( +qc_log_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, +qc_display_method ENUM('CALL','LEAD') DEFAULT 'CALL', +lead_id INT(10) UNSIGNED DEFAULT NULL, +status VARCHAR(6) DEFAULT NULL, +call_date DATETIME DEFAULT NULL, +agent_log_id INT(9) UNSIGNED DEFAULT NULL, +user VARCHAR(20) DEFAULT NULL, +user_group VARCHAR(20) DEFAULT NULL, +campaign_id VARCHAR(8) DEFAULT NULL, +group_id VARCHAR(20) DEFAULT NULL, +list_id BIGINT(14) UNSIGNED DEFAULT NULL, +scorecard_source ENUM('CAMPAIGN','INGROUP','LIST') DEFAULT 'CAMPAIGN', +qc_web_form_address VARCHAR(255) DEFAULT NULL, +vicidial_id VARCHAR(20) DEFAULT NULL, +recording_id INT(10) UNSIGNED DEFAULT NULL, +qc_scorecard_id VARCHAR(20) DEFAULT NULL, +qc_agent VARCHAR(20) DEFAULT NULL, +qc_user_group VARCHAR(20) DEFAULT NULL, +qc_status VARCHAR(20) DEFAULT NULL, +date_modified TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), +date_claimed DATETIME DEFAULT NULL, +date_completed DATETIME DEFAULT NULL, +PRIMARY KEY (qc_log_id), +UNIQUE KEY quality_control_queue_agent_log_id_key (agent_log_id), +KEY quality_control_queue_lead_id_key (lead_id) +) ENGINE=MyISAM; + +CREATE TABLE quality_control_scorecards ( +qc_scorecard_id VARCHAR(20) NOT NULL, +scorecard_name VARCHAR(255) DEFAULT NULL, +active ENUM('Y','N') DEFAULT 'Y', +passing_score SMALLINT(5) UNSIGNED DEFAULT 0, +last_modified TIMESTAMP NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), +PRIMARY KEY (qc_scorecard_id) +) ENGINE=MyISAM; + +ALTER TABLE vicidial_campaigns ADD qc_scorecard_id VARCHAR(20) DEFAULT ''; +ALTER TABLE vicidial_campaigns ADD qc_statuses_id VARCHAR(20) DEFAULT ''; + +ALTER TABLE vicidial_lists ADD qc_scorecard_id VARCHAR(20) DEFAULT ''; +ALTER TABLE vicidial_lists ADD qc_statuses_id VARCHAR(20) DEFAULT ''; +ALTER TABLE vicidial_lists ADD qc_web_form_address VARCHAR(255) DEFAULT ''; + +ALTER TABLE vicidial_inbound_groups ADD qc_scorecard_id VARCHAR(20) DEFAULT ''; +ALTER TABLE vicidial_inbound_groups ADD qc_statuses_id VARCHAR(20) DEFAULT ''; + +ALTER TABLE system_settings ADD qc_claim_limit TINYINT UNSIGNED DEFAULT '3'; +ALTER TABLE system_settings ADD qc_expire_days TINYINT UNSIGNED DEFAULT '3'; + +INSERT INTO vicidial_settings_containers(container_id,container_notes,container_type,user_group,container_entry) VALUES ('QC_STATUS_TEMPLATE','Sample QC Status Template','QC_TEMPLATE','---ALL---','# These types of containers are simply used for creating a list of \r\n# QC-enabled statuses to apply to campaigns, lists, and ingroups.\r\n# Simply put all the statuses that this template should allow in\r\n# a comma-delimited string, as below:\r\n\r\nSALE,DNC,NI'); + +UPDATE system_settings SET db_schema_version='1619',db_schema_update_date=NOW() where db_schema_version < 1619; diff --git a/agc_2-X/trunk/www/vicidial/AST_quality_control_report.php b/agc_2-X/trunk/www/vicidial/AST_quality_control_report.php new file mode 100644 index 00000000..93de5140 --- /dev/null +++ b/agc_2-X/trunk/www/vicidial/AST_quality_control_report.php @@ -0,0 +1,1040 @@ + LICENSE: AGPLv2 +# +# Report for QC activity within VICIdial +# +# changes: +# 210306-1556 - First Build +# + +$admin_version = '2.14-1'; +$build = '210306-1556'; + + +$startMS = microtime(); + +require("dbconnect_mysqli.php"); +require("functions.php"); + + +$PHP_AUTH_USER=$_SERVER['PHP_AUTH_USER']; +$PHP_AUTH_PW=$_SERVER['PHP_AUTH_PW']; +$PHP_SELF=$_SERVER['PHP_SELF']; +if (isset($_GET["query_date"])) {$query_date=$_GET["query_date"];} + elseif (isset($_POST["query_date"])) {$query_date=$_POST["query_date"];} +if (isset($_GET["end_date"])) {$end_date=$_GET["end_date"];} + elseif (isset($_POST["end_date"])) {$end_date=$_POST["end_date"];} +if (isset($_GET["query_time"])) {$query_time=$_GET["query_time"];} + elseif (isset($_POST["query_time"])) {$query_time=$_POST["query_time"];} +if (isset($_GET["end_time"])) {$end_time=$_GET["end_time"];} + elseif (isset($_POST["end_time"])) {$end_time=$_POST["end_time"];} +if (isset($_GET["qc_finish_start_date"])) {$qc_finish_start_date=$_GET["qc_finish_start_date"];} + elseif (isset($_POST["qc_finish_start_date"])) {$qc_finish_start_date=$_POST["qc_finish_start_date"];} +if (isset($_GET["qc_finish_end_date"])) {$qc_finish_end_date=$_GET["qc_finish_end_date"];} + elseif (isset($_POST["qc_finish_end_date"])) {$qc_finish_end_date=$_POST["qc_finish_end_date"];} +if (isset($_GET["qc_finish_start_time"])) {$qc_finish_start_time=$_GET["qc_finish_start_time"];} + elseif (isset($_POST["qc_finish_start_time"])) {$qc_finish_start_time=$_POST["qc_finish_start_time"];} +if (isset($_GET["qc_finish_end_time"])) {$qc_finish_end_time=$_GET["qc_finish_end_time"];} + elseif (isset($_POST["qc_finish_end_time"])) {$qc_finish_end_time=$_POST["qc_finish_end_time"];} + +if (isset($_GET["group"])) {$group=$_GET["group"];} + elseif (isset($_POST["group"])) {$group=$_POST["group"];} +if (isset($_GET["users"])) {$users=$_GET["users"];} + elseif (isset($_POST["users"])) {$users=$_POST["users"];} +if (isset($_GET["user_groups"])) {$user_groups=$_GET["user_groups"];} + elseif (isset($_POST["user_groups"])) {$user_groups=$_POST["user_groups"];} +if (isset($_GET["statuses"])) {$statuses=$_GET["statuses"];} + elseif (isset($_POST["statuses"])) {$statuses=$_POST["statuses"];} +if (isset($_GET["QCusers"])) {$QCusers=$_GET["QCusers"];} + elseif (isset($_POST["QCusers"])) {$QCusers=$_POST["QCusers"];} +if (isset($_GET["QCuser_groups"])) {$QCuser_groups=$_GET["QCuser_groups"];} + elseif (isset($_POST["QCuser_groups"])) {$QCuser_groups=$_POST["QCuser_groups"];} +if (isset($_GET["QCstatuses"])) {$QCstatuses=$_GET["QCstatuses"];} + elseif (isset($_POST["QCstatuses"])) {$QCstatuses=$_POST["QCstatuses"];} +if (isset($_GET["DB"])) {$DB=$_GET["DB"];} + elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];} +if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];} + elseif (isset($_POST["SUBMIT"])) {$SUBMIT=$_POST["SUBMIT"];} +if (isset($_GET["show_percentages"])) {$show_percentages=$_GET["show_percentages"];} + elseif (isset($_POST["show_percentages"])) {$show_percentages=$_POST["show_percentages"];} +if (isset($_GET["file_download"])) {$file_download=$_GET["file_download"];} + elseif (isset($_POST["file_download"])) {$file_download=$_POST["file_download"];} + +$report_name = 'Quality Control Report'; +$db_source = 'M'; +$report_display_type="HTML"; + +############################################# +##### START SYSTEM_SETTINGS LOOKUP ##### +$stmt = "SELECT use_non_latin,outbound_autodial_active,slave_db_server,reports_use_slave_db,enable_languages,language_method,report_default_format,qc_features_active FROM system_settings;"; +$rslt=mysql_to_mysqli($stmt, $link); +if ($DB) {$HTML_text.="$stmt\n";} +$qm_conf_ct = mysqli_num_rows($rslt); +if ($qm_conf_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $non_latin = $row[0]; + $outbound_autodial_active = $row[1]; + $slave_db_server = $row[2]; + $reports_use_slave_db = $row[3]; + $SSenable_languages = $row[4]; + $SSlanguage_method = $row[5]; + $SSreport_default_format = $row[6]; + $SSqc_features_active = $row[7]; + } +##### END SETTINGS LOOKUP ##### +########################################### +if (strlen($report_display_type)<2) {$report_display_type = $SSreport_default_format;} + +### ARCHIVED DATA CHECK CONFIGURATION +$archives_available="N"; +$log_tables_array=array("quality_control_queue", "quality_control_checkpoint_log"); +for ($t=0; $t 0) + { + $row=mysqli_fetch_row($rslt); + $VUselected_language = $row[0]; + $qc_auth = $row[1]; + } + +$auth=0; +$reports_auth=0; +$admin_auth=0; +$auth_message = user_authorization($PHP_AUTH_USER,$PHP_AUTH_PW,'REPORTS',1,0); +if ($auth_message == 'GOOD') + {$auth=1;} + +if ($auth > 0) + { + $stmt="SELECT count(*) from vicidial_users where user='$PHP_AUTH_USER' and user_level > 7 and view_reports='1';"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_row($rslt); + $admin_auth=$row[0]; + + $stmt="SELECT count(*) from vicidial_users where user='$PHP_AUTH_USER' and user_level > 6 and view_reports='1';"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_row($rslt); + $reports_auth=$row[0]; + + if ($reports_auth < 1) + { + $VDdisplayMESSAGE = _QXZ("You are not allowed to view reports"); + Header ("Content-type: text/html; charset=utf-8"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; + exit; + } + if ( ($reports_auth > 0) and ($admin_auth < 1) ) + { + $ADD=999999; + $reports_only_user=1; + } + } +else + { + $VDdisplayMESSAGE = _QXZ("Login incorrect, please try again"); + if ($auth_message == 'LOCK') + { + $VDdisplayMESSAGE = _QXZ("Too many login attempts, try again in 15 minutes"); + Header ("Content-type: text/html; charset=utf-8"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; + exit; + } + if ($auth_message == 'IPBLOCK') + { + $VDdisplayMESSAGE = _QXZ("Your IP Address is not allowed") . ": $ip"; + Header ("Content-type: text/html; charset=utf-8"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; + exit; + } + Header("WWW-Authenticate: Basic realm=\"CONTACT-CENTER-ADMIN\""); + Header("HTTP/1.0 401 Unauthorized"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$PHP_AUTH_PW|$auth_message|\n"; + exit; + } + +##### BEGIN log visit to the vicidial_report_log table ##### +$LOGip = getenv("REMOTE_ADDR"); +$LOGbrowser = getenv("HTTP_USER_AGENT"); +$LOGscript_name = getenv("SCRIPT_NAME"); +$LOGserver_name = getenv("SERVER_NAME"); +$LOGserver_port = getenv("SERVER_PORT"); +$LOGrequest_uri = getenv("REQUEST_URI"); +$LOGhttp_referer = getenv("HTTP_REFERER"); +$LOGbrowser=preg_replace("/\'|\"|\\\\/","",$LOGbrowser); +$LOGrequest_uri=preg_replace("/\'|\"|\\\\/","",$LOGrequest_uri); +$LOGhttp_referer=preg_replace("/\'|\"|\\\\/","",$LOGhttp_referer); +if (preg_match("/443/i",$LOGserver_port)) {$HTTPprotocol = 'https://';} + else {$HTTPprotocol = 'http://';} +if (($LOGserver_port == '80') or ($LOGserver_port == '443') ) {$LOGserver_port='';} +else {$LOGserver_port = ":$LOGserver_port";} +$LOGfull_url = "$HTTPprotocol$LOGserver_name$LOGserver_port$LOGrequest_uri"; + +$LOGhostname = php_uname('n'); +if (strlen($LOGhostname)<1) {$LOGhostname='X';} +if (strlen($LOGserver_name)<1) {$LOGserver_name='X';} + +$stmt="SELECT webserver_id FROM vicidial_webservers where webserver='$LOGserver_name' and hostname='$LOGhostname' LIMIT 1;"; +$rslt=mysql_to_mysqli($stmt, $link); +if ($DB) {echo "$stmt\n";} +$webserver_id_ct = mysqli_num_rows($rslt); +if ($webserver_id_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $webserver_id = $row[0]; + } +else + { + ##### insert webserver entry + $stmt="INSERT INTO vicidial_webservers (webserver,hostname) values('$LOGserver_name','$LOGhostname');"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $affected_rows = mysqli_affected_rows($link); + $webserver_id = mysqli_insert_id($link); + } + +$stmt="INSERT INTO vicidial_report_log set event_date=NOW(), user='$PHP_AUTH_USER', ip_address='$LOGip', report_name='$report_name', browser='$LOGbrowser', referer='$LOGhttp_referer', notes='$LOGserver_name:$LOGserver_port $LOGscript_name |$group[0], $query_date, $end_date, $shift, $file_download, $report_display_type|', url='$LOGfull_url', webserver='$webserver_id';"; +if ($DB) {echo "|$stmt|\n";} +$rslt=mysql_to_mysqli($stmt, $link); +$report_log_id = mysqli_insert_id($link); +##### END log visit to the vicidial_report_log table ##### + +if ( (strlen($slave_db_server)>5) and (preg_match("/$report_name/",$reports_use_slave_db)) ) + { + mysqli_close($link); + $use_slave_server=1; + $db_source = 'S'; + require("dbconnect_mysqli.php"); + $HTML_text.="\n"; + } + +$stmt="SELECT user_group from vicidial_users where user='$PHP_AUTH_USER';"; +if ($DB) {$HTML_text.="|$stmt|\n";} +$rslt=mysql_to_mysqli($stmt, $link); +$row=mysqli_fetch_row($rslt); +$LOGuser_group = $row[0]; + +$stmt="SELECT allowed_campaigns,allowed_reports,admin_viewable_groups,admin_viewable_call_times from vicidial_user_groups where user_group='$LOGuser_group';"; +if ($DB) {$HTML_text.="|$stmt|\n";} +$rslt=mysql_to_mysqli($stmt, $link); +$row=mysqli_fetch_row($rslt); +$LOGallowed_campaigns = $row[0]; +$LOGallowed_reports = $row[1]; +$LOGadmin_viewable_groups = $row[2]; +$LOGadmin_viewable_call_times = $row[3]; + +if ( (!preg_match("/$report_name/",$LOGallowed_reports)) and (!preg_match("/ALL REPORTS/",$LOGallowed_reports)) ) + { + Header("WWW-Authenticate: Basic realm=\"CONTACT-CENTER-ADMIN\""); + Header("HTTP/1.0 401 Unauthorized"); + echo _QXZ("You are not allowed to view this report").": |$PHP_AUTH_USER|$report_name|\n"; + exit; + } + +$LOGallowed_campaignsSQL=''; +$whereLOGallowed_campaignsSQL=''; +if ( (!preg_match('/\-ALL/i', $LOGallowed_campaigns)) ) + { + $rawLOGallowed_campaignsSQL = preg_replace("/ -/",'',$LOGallowed_campaigns); + $rawLOGallowed_campaignsSQL = preg_replace("/ /","','",$rawLOGallowed_campaignsSQL); + $LOGallowed_campaignsSQL = "and campaign_id IN('$rawLOGallowed_campaignsSQL')"; + $whereLOGallowed_campaignsSQL = "where campaign_id IN('$rawLOGallowed_campaignsSQL')"; + } +$regexLOGallowed_campaigns = " $LOGallowed_campaigns "; + +$LOGadmin_viewable_groupsSQL=''; +$whereLOGadmin_viewable_groupsSQL=''; +if ( (!preg_match('/\-\-ALL\-\-/i',$LOGadmin_viewable_groups)) and (strlen($LOGadmin_viewable_groups) > 3) ) + { + $rawLOGadmin_viewable_groupsSQL = preg_replace("/ -/",'',$LOGadmin_viewable_groups); + $rawLOGadmin_viewable_groupsSQL = preg_replace("/ /","','",$rawLOGadmin_viewable_groupsSQL); + $LOGadmin_viewable_groupsSQL = "and user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')"; + $whereLOGadmin_viewable_groupsSQL = "where user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')"; + } + + + +$MT[0]=''; +$NOW_DATE = date("Y-m-d"); +$NOW_TIME = date("Y-m-d H:i:s"); +$STARTtime = date("U"); +if (!isset($group)) {$group = array();} +if (!isset($statuses)) {$statuses = array();} +if (!isset($users)) {$users = array();} +if (!isset($user_groups)) {$user_groups = array();} +if (!isset($QCusers)) {$QCusers = array();} +if (!isset($QCstatuses)) {$QCstatuses = array();} +if (!isset($QCuser_groups)) {$QCuser_groups = array();} +if (!isset($query_date)) {$query_date = $NOW_DATE;} +if (!isset($end_date)) {$end_date = $NOW_DATE;} +if (!isset($query_time)) {$query_time = "00:00:00";} +if (!isset($end_time)) {$end_time = "23:59:59";} +#if (!isset($qc_finish_start_date)) {$qc_finish_start_date = $NOW_DATE;} +#if (!isset($qc_finish_end_date)) {$qc_finish_end_date = $NOW_DATE;} +#if (!isset($qc_finish_start_time)) {$qc_finish_start_time = "00:00:00";} +#if (!isset($qc_finish_end_time)) {$qc_finish_end_time = "23:59:59";} +$all_QC_statuses=array("CLAIMED", "FINISHED"); +$QC_statuses_to_print=count($all_QC_statuses); + +$i=0; +$campaign_string='|'; +$campaigns_ct = count($group); +while($i < $campaigns_ct) + { + $campaign_string .= "$group[$i]|"; + $i++; + } + +$i=0; +$users_string='|'; +$users_ct = count($users); +while($i < $users_ct) + { + $users_string .= "$users[$i]|"; + $i++; + } + +$i=0; +$QCusers_string='|'; +$QCusers_ct = count($QCusers); +while($i < $QCusers_ct) + { + $QCusers_string .= "$QCusers[$i]|"; + $i++; + } + +$i=0; +$QCstatuses_string='|'; +$QCstatuses_ct = count($QCstatuses); +while($i < $QCstatuses_ct) + { + $QCstatuses_string .= "$QCstatuses[$i]|"; + $i++; + } + +$stmt="SELECT campaign_id from vicidial_campaigns $whereLOGallowed_campaignsSQL order by campaign_id;"; +$rslt=mysql_to_mysqli($stmt, $link); +if ($DB) {$HTML_text.="$stmt\n";} +$campaigns_to_print = mysqli_num_rows($rslt); +$i=0; +$groups=array(); +while ($i < $campaigns_to_print) + { + $row=mysqli_fetch_row($rslt); + $groups[$i] =$row[0]; + if (preg_match('/\-ALL/',$group_string) ) + {$group[$i] = $groups[$i];} + $i++; + } +#for ($i=0; $i\"HELP\""; + +$NWB = "\"HELP\""; + + +$HTML_head.="\n"; +$HTML_head.="\n"; +$HTML_head.="\n"; + + +$HTML_head.="\n"; +$HTML_head.="\n"; +$HTML_head.="\n"; +$HTML_head.="\n"; +$HTML_head.="\n"; +$HTML_head.="\n"; +$HTML_head.=""._QXZ("$report_name")."\n"; +$HTML_head.=""; + + $short_header=1; + +# require("admin_header.php"); + +$HTML_text.="
"; +$HTML_text.=""._QXZ("$report_name")." ".$NWB."quality_control_report".$NWE."\n"; + +$HTML_text.="
\n"; +$HTML_text.=""; + +$HTML_text.=""; + +/* +$HTML_text.=""; +*/ + +$HTML_text.=""; + +$HTML_text.=""; + +$HTML_text.=""; + +$HTML_text.=""; + +$HTML_text.="\n"; + +/* +$HTML_text.=""; +*/ + +$HTML_text.=""; + +$HTML_text.=""; + +$HTML_text.="
"._QXZ("Call dates").":
"; +$HTML_text.="\n"; +$HTML_text.=""; + +$HTML_text.="\n"; + +$HTML_text.="  "; + +$HTML_text.="
"._QXZ("to")."
"; + +$HTML_text.="\n"; + +$HTML_text.="  "; +$HTML_text.="
"._QXZ("Campaigns").":
"; +$HTML_text.="\n"; +$HTML_text.="
"._QXZ("User Groups").":
"; +$HTML_text.="\n"; +$HTML_text.="
"._QXZ("Users").":
"; +$HTML_text.="\n"; +$HTML_text.="
        "; +$HTML_text.="          \n"; +$HTML_text.=" "._QXZ("REPORTS")."

\n"; +$HTML_text.=""._QXZ("Show %s")."
\n"; +$HTML_text.=""._QXZ("Search archived data")."
\n"; +$HTML_text.="

\n"; +$HTML_text.="       \n"; +$HTML_text.="
"._QXZ("Finish date").":
"; +$HTML_text.=""; + +$HTML_text.="\n"; + +$HTML_text.="  "; + +$HTML_text.="
"._QXZ("to")."
"; + +$HTML_text.="\n"; + +$HTML_text.="  "; +$HTML_text.="
"._QXZ("QC Status").":
"; +$HTML_text.="\n"; +$HTML_text.="
"._QXZ("QC User Groups").":
"; +$HTML_text.="\n"; +$HTML_text.="
"._QXZ("QC Users").":
"; +$HTML_text.="\n"; +$HTML_text.="
"; + +$HTML_text.="
\n\n"; + + +if ($SUBMIT && ($QCuser_ct>0 || $user_ct>0 || $group_ct>0 || $QCstatus_ct>0 || ($qc_finish_start_date && $qc_finish_end_date)) ) + { + if ($qc_finish_start_date && $qc_finish_end_date) + { + if (!$qc_finish_start_time) {$qc_finish_start_time = "00:00:00";} + if (!$qc_finish_end_time) {$qc_finish_end_time = "23:59:59";} + $finish_date_clause=" and date_completed>='$qc_finish_start_date $qc_finish_start_time' and date_completed<='$qc_finish_end_date $qc_finish_end_time'"; + } + + $qc_stmt="select * from ".$quality_control_queue_table." where call_date>='$query_date $query_time' and call_date<='$end_date $end_time' $finish_date_clause $group_SQL $QCstatus_QC_log_SQL $user_QC_log_SQL $QCuser_QC_log_SQL"; + if ($DB) {$HTML_text.=$qc_stmt."

";} + + $qc_rslt=mysql_to_mysqli($qc_stmt, $link); + + if(mysqli_num_rows($qc_rslt)>0) + { + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + + $CSV_header="\"Call date\",\"Call agent\",\"Lead ID\",\"Campaign ID\",\"Status\",\"Scorecard\",\"QC agent\",\"Claim date\",\"Finish date\",\"Score\",\"Instant fail\",\"Result\",\"QC status\""; + $CSV_text=""; + + $x=0; + $max_questions=0; + while ($qc_row=mysqli_fetch_array($qc_rslt)) + { + if ($x%2==0) {$bgcolor=$SSstd_row2_background;} else {$bgcolor=$SSstd_row1_background;} + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $instant_fail=GetFail($qc_row["qc_log_id"]); + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + + $CSV_text.="\"".$qc_row["call_date"]."\",\"".GetFullName($qc_row["user"])."\",\"".$qc_row["lead_id"]."\",\"".$qc_row["campaign_id"]."\",\"".$qc_row["status"]."\",\"".$qc_row["qc_scorecard_id"]."\",\"".GetFullName($qc_row["qc_agent"])."\",\"".$qc_row["date_claimed"]."\",\"".$qc_row["date_completed"]."\",\"".GetScore($qc_row["qc_log_id"], "")."\",\"".$instant_fail."\",\"".($instant_fail=="Y" ? "FAILED" : GetResult($qc_row["qc_log_id"]))."\",\"".$qc_row["qc_status"]."\""; + + $checkpoint_stmt="select * from ".$quality_control_checkpoint_log_table." where qc_log_id='".$qc_row["qc_log_id"]."' order by checkpoint_rank asc"; + if ($DB) {$HTML_text.=$checkpoint_stmt."
";} + $checkpoint_rslt=mysql_to_mysqli($checkpoint_stmt, $link); + $question_count=mysqli_num_rows($checkpoint_rslt); + if ($question_count>$max_questions) {$max_questions=$question_count;} + while($crow=mysqli_fetch_array($checkpoint_rslt)) + { + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $HTML_text.=""; + $CSV_text.=",\"".$crow["checkpoint_rank"].") ".$crow["checkpoint_text"]."\",\"".$crow["checkpoint_comment_agent"]."\",\"".GetScore($qc_row["qc_log_id"], $crow["qc_checkpoint_log_id"])."\",\"".$crow["instant_fail"]."\""; + } + $CSV_text.="\n"; + + $x++; + } + + for ($i=1; $i<=$max_questions; $i++) + { + $CSV_header.=",\"Checkpoint $i\",\"Comments $i\",\"Score $i\",\"Instant fail $i\""; + } + $CSV_header.="\n"; + + $HTML_text.="
[DOWNLOAD]
Call dateCall agentLead IDCampaign IDStatusScorecardQC agentClaim dateFinish dateScoreInstant failResultQC status
".$qc_row["call_date"]."".GetFullName($qc_row["user"])."".$qc_row["lead_id"]."".$qc_row["campaign_id"]."".$qc_row["status"]."".$qc_row["qc_scorecard_id"]."".GetFullName($qc_row["qc_agent"])."".$qc_row["date_claimed"]."".$qc_row["date_completed"]."".GetScore($qc_row["qc_log_id"], "")."".$instant_fail."".($instant_fail=="Y" ? "FAILED" : GetResult($qc_row["qc_log_id"]))."".$qc_row["qc_status"]."
    ".$crow["checkpoint_rank"].") ".$crow["checkpoint_text"]."".$crow["checkpoint_comment_agent"]."".GetScore($qc_row["qc_log_id"], $crow["qc_checkpoint_log_id"])."".$crow["instant_fail"]." 
"; + + } + else + { + $HTML_text.="*** NO RESULTS FOUND ***"; + } + + } + +$HTML_text.="\n\n
"; +$HTML_text.="
"; + +$HTML_text.=""; + + + + + + + + + +if ($file_download == 0 || !$file_download) + { + echo $HTML_head; + require("admin_header.php"); + echo $HTML_text; + echo "\n"; + } +else + { + $FILE_TIME = date("Ymd-His"); + $CSVfilename = "Quality_control_rpt_$US$FILE_TIME.csv"; + $CSV_text="$CSV_header$CSV_text"; + $CSV_text=preg_replace('/^\s+/', '', $CSV_text); + $CSV_text=preg_replace('/ +\"/', '"', $CSV_text); + $CSV_text=preg_replace('/\" +/', '"', $CSV_text); + // We'll be outputting a TXT file + header('Content-type: application/octet-stream'); + + // It will be called LIST_101_20090209-121212.txt + header("Content-Disposition: attachment; filename=\"$CSVfilename\""); + header('Expires: 0'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Pragma: public'); + ob_clean(); + flush(); + + echo "$CSV_text"; + } + +if ($db_source == 'S') + { + mysqli_close($link); + $use_slave_server=0; + $db_source = 'M'; + require("dbconnect_mysqli.php"); + } + +$endMS = microtime(); +$startMSary = explode(" ",$startMS); +$endMSary = explode(" ",$endMS); +$runS = ($endMSary[0] - $startMSary[0]); +$runM = ($endMSary[1] - $startMSary[1]); +$TOTALrun = ($runS + $runM); + +#$stmt="UPDATE vicidial_report_log set run_time='$TOTALrun' where report_log_id='$report_log_id';"; +#if ($DB) {echo "|$stmt|\n";} +#$rslt=mysql_to_mysqli($stmt, $link); + +function GetFullName($full_name) + { + global $link, $DB; + $name_stmt="select full_name from vicidial_users where user='$full_name'"; + $name_rslt=mysql_to_mysqli($name_stmt, $link); + while ($name_row=mysqli_fetch_array($name_rslt)) + { + $full_name=$name_row["full_name"]; + } + return $full_name; + } + +function GetFail($QCID) + { + global $link, $DB; + $fail_stmt="select count(*) From quality_control_checkpoint_log where qc_log_id='$QCID' and instant_fail='Y'"; + $fail_rslt=mysql_to_mysqli($fail_stmt, $link); + while ($fail_row=mysqli_fetch_row($fail_rslt)) + { + $fail_count=$fail_row[0]; + } + if ($fail_count>0) {return "Y";} else {return "N";} + } + +function GetResult($QCID) + { + global $link, $DB, $show_percentages; + $passing_score=0; + $total_score=0; + + $score_stmt="select qc_scorecard_id, sum(checkpoint_points_earned) from quality_control_checkpoint_log where qc_log_id='$QCID'"; + if ($DB) {echo $score_stmt."
\n";} + $score_rslt=mysql_to_mysqli($score_stmt, $link); + while ($score_row=mysqli_fetch_array($score_rslt)) + { + $scorecard_id=$score_row[0]; + $total_score=$score_row[1]; + $result_stmt="select passing_score from quality_control_scorecards where qc_scorecard_id='$scorecard_id'"; + $result_rslt=mysql_to_mysqli($result_stmt, $link); + $result_row=mysqli_fetch_array($result_rslt); + $passing_score=$result_row[0]; + } + + return ($total_score>=$passing_score ? "PASSED" : "FAILED"); + + } + +function GetScore($QCID, $checkpointID) + { + global $link, $DB, $show_percentages; + $score="--"; + + $checkpoint_clause=""; + if ($checkpointID) {$checkpoint_clause=" and qc_checkpoint_log_id='$checkpointID'";} + + $score_stmt="select sum(checkpoint_points), sum(checkpoint_points_earned) from quality_control_checkpoint_log where qc_log_id='$QCID' $checkpoint_clause"; + if ($DB) {echo $score_stmt."
\n";} + $score_rslt=mysql_to_mysqli($score_stmt, $link); + $new_lead_IDs=array(); + while ($score_row=mysqli_fetch_array($score_rslt)) + { + if ($show_percentages) + { + $score=sprintf("%.2f", (100*($score_row[1]/$score_row[0])))." %"; + } + else + { + $score=$score_row[1]." / ".$score_row[0]; + } + } + return $score; + } + + +exit; +?> + diff --git a/agc_2-X/trunk/www/vicidial/admin.php b/agc_2-X/trunk/www/vicidial/admin.php index f978ad2b..e5a25ce1 100644 --- a/agc_2-X/trunk/www/vicidial/admin.php +++ b/agc_2-X/trunk/www/vicidial/admin.php @@ -122,9 +122,9 @@ $PHP_AUTH_PW=$_SERVER['PHP_AUTH_PW']; $PHP_SELF=$_SERVER['PHP_SELF']; $QUERY_STRING = getenv("QUERY_STRING"); -$Vreports = 'NONE, Real-Time Main Report, Real-Time Campaign Summary, Real-Time Whiteboard Report, Inbound Report, Inbound Report by DID, Inbound Service Level Report, Inbound Summary Hourly Report, Inbound Daily Report, Inbound DID Report, Inbound DID Summary Report, Agent DID Report, Inbound IVR Report, Inbound Forecasting Report, Advanced Forecasting Report, Outbound Calling Report, Outbound Summary Interval Report, Outbound IVR Report, Callmenu Survey Report, Outbound Lead Source Report, Fronter - Closer Report, Fronter - Closer Detail Report, Lists Campaign Statuses Report, Lists Statuses Report, Campaign Status List Report, Export Calls Report, Export Leads Report, Agent Time Detail, Agent Status Detail, Agent Inbound Status Summary, Agent Performance Detail, Team Performance Detail, Performance Comparison Report, Single Agent Daily, Single Agent Daily Time, User Group Login Report, User Group Hourly Report, User Group Detail Hourly Report, User Timeclock Report, User Group Timeclock Status Report, User Timeclock Detail Report, Server Performance Report, Administration Change Log, List Update Stats, User Stats, User Time Sheet, Download List, Dialer Inventory Report, Maximum System Stats, Maximum Stats Detail, Search Leads Logs, Email Log Report, Carrier Log Report, Campaign Debug, Shared Debug, Asterisk Debug, Hangup Cause Report, Lists Pass Report, Called Counts List IDs Report, Agent Debug Log Report, Agent Parked Call Report, Agent-Manager Chat Log, Recording Access Log Report, API Log Report, Real-Time Monitoring Log Report, AMD Log Report, SIP Event Report, Caller ID Log Report'; +$Vreports = 'NONE, Real-Time Main Report, Real-Time Campaign Summary, Real-Time Whiteboard Report, Inbound Report, Inbound Report by DID, Inbound Service Level Report, Inbound Summary Hourly Report, Inbound Daily Report, Inbound DID Report, Inbound DID Summary Report, Agent DID Report, Inbound IVR Report, Inbound Forecasting Report, Advanced Forecasting Report, Outbound Calling Report, Outbound Summary Interval Report, Outbound IVR Report, Callmenu Survey Report, Outbound Lead Source Report, Fronter - Closer Report, Fronter - Closer Detail Report, Lists Campaign Statuses Report, Lists Statuses Report, Campaign Status List Report, Export Calls Report, Export Leads Report, Agent Time Detail, Agent Status Detail, Agent Inbound Status Summary, Agent Performance Detail, Team Performance Detail, Performance Comparison Report, Single Agent Daily, Single Agent Daily Time, User Group Login Report, User Group Hourly Report, User Group Detail Hourly Report, User Timeclock Report, User Group Timeclock Status Report, User Timeclock Detail Report, Server Performance Report, Administration Change Log, List Update Stats, User Stats, User Time Sheet, Download List, Dialer Inventory Report, Maximum System Stats, Maximum Stats Detail, Search Leads Logs, Email Log Report, Carrier Log Report, Campaign Debug, Shared Debug, Asterisk Debug, Hangup Cause Report, Lists Pass Report, Called Counts List IDs Report, Agent Debug Log Report, Agent Parked Call Report, Agent-Manager Chat Log, Recording Access Log Report, API Log Report, Real-Time Monitoring Log Report, AMD Log Report, SIP Event Report, Caller ID Log Report, Quality Control Report, Settings Compare'; -$UGreports = 'ALL REPORTS, NONE, Real-Time Main Report, Real-Time Campaign Summary, Real-Time Whiteboard Report, Inbound Report, Inbound Report by DID, Inbound Service Level Report, Inbound Summary Hourly Report, Inbound Daily Report, Inbound DID Report, Inbound DID Summary Report, Agent DID Report, Inbound Email Report, Inbound Chat Report, Inbound IVR Report, Inbound Forecasting Report, Advanced Forecasting Report, Outbound Calling Report, Outbound Summary Interval Report, Outbound IVR Report, Callmenu Survey Report, Outbound Lead Source Report, Fronter - Closer Report, Fronter - Closer Detail Report, Lists Campaign Statuses Report, Lists Statuses Report, Campaign Status List Report, Export Calls Report, Export Leads Report, Agent Time Detail, Agent Status Detail, Agent Inbound Status Summary, Agent Performance Detail, Team Performance Detail, Performance Comparison Report, Single Agent Daily, Single Agent Daily Time, User Group Login Report, User Group Hourly Report, User Group Detail Hourly Report, User Timeclock Report, User Group Timeclock Status Report, User Timeclock Detail Report, Server Performance Report, Administration Change Log, List Update Stats, User Stats, User Time Sheet, Download List, Dialer Inventory Report, Custom Reports Links, CallCard Search, Maximum System Stats, Maximum Stats Detail, Search Leads Logs, Email Log Report, Lists Pass Report, Called Counts List IDs Report, Front Page System Summary, Report Page Servers Summary, Admin Utilities Page, Agent Debug Log Report, Agent Parked Call Report, Agent-Manager Chat Log, Recording Access Log Report, API Log Report, Real-Time Monitoring Log Report, AMD Log Report, SIP Event Report, Caller ID Log Report'; +$UGreports = 'ALL REPORTS, NONE, Real-Time Main Report, Real-Time Campaign Summary, Real-Time Whiteboard Report, Inbound Report, Inbound Report by DID, Inbound Service Level Report, Inbound Summary Hourly Report, Inbound Daily Report, Inbound DID Report, Inbound DID Summary Report, Agent DID Report, Inbound Email Report, Inbound Chat Report, Inbound IVR Report, Inbound Forecasting Report, Advanced Forecasting Report, Outbound Calling Report, Outbound Summary Interval Report, Outbound IVR Report, Callmenu Survey Report, Outbound Lead Source Report, Fronter - Closer Report, Fronter - Closer Detail Report, Lists Campaign Statuses Report, Lists Statuses Report, Campaign Status List Report, Export Calls Report, Export Leads Report, Agent Time Detail, Agent Status Detail, Agent Inbound Status Summary, Agent Performance Detail, Team Performance Detail, Performance Comparison Report, Single Agent Daily, Single Agent Daily Time, User Group Login Report, User Group Hourly Report, User Group Detail Hourly Report, User Timeclock Report, User Group Timeclock Status Report, User Timeclock Detail Report, Server Performance Report, Administration Change Log, List Update Stats, User Stats, User Time Sheet, Download List, Dialer Inventory Report, Custom Reports Links, CallCard Search, Maximum System Stats, Maximum Stats Detail, Search Leads Logs, Email Log Report, Lists Pass Report, Called Counts List IDs Report, Front Page System Summary, Report Page Servers Summary, Admin Utilities Page, Agent Debug Log Report, Agent Parked Call Report, Agent-Manager Chat Log, Recording Access Log Report, API Log Report, Real-Time Monitoring Log Report, AMD Log Report, SIP Event Report, Caller ID Log Report, Quality Control Report, Settings Compare'; $Vtables = 'NONE,log_noanswer,did_agent_log,contact_information'; @@ -794,6 +794,12 @@ if (isset($_GET["qc_campaigns"])) {$qc_campaigns=$_GET["qc_campaigns"];} elseif (isset($_POST["qc_campaigns"])) {$qc_campaigns=$_POST["qc_campaigns"];} if (isset($_GET["qc_groups"])) {$qc_groups=$_GET["qc_groups"];} elseif (isset($_POST["qc_groups"])) {$qc_groups=$_POST["qc_groups"];} +if (isset($_GET["qc_display_group_type"])) {$qc_display_group_type=$_GET["qc_display_group_type"];} + elseif (isset($_POST["qc_display_group_type"])) {$qc_display_group_type=$_POST["qc_display_group_type"];} +if (isset($_GET["qc_claim_limit"])) {$qc_claim_limit=$_GET["qc_claim_limit"];} + elseif (isset($_POST["qc_claim_limit"])) {$qc_claim_limit=$_POST["qc_claim_limit"];} +if (isset($_GET["qc_expire_days"])) {$qc_expire_days=$_GET["qc_expire_days"];} + elseif (isset($_POST["qc_expire_days"])) {$qc_expire_days=$_POST["qc_expire_days"];} if (isset($_GET["queue_priority"])) {$queue_priority=$_GET["queue_priority"];} elseif (isset($_POST["queue_priority"])) {$queue_priority=$_POST["queue_priority"];} if (isset($_GET["drop_inbound_group"])) {$drop_inbound_group=$_GET["drop_inbound_group"];} @@ -802,6 +808,10 @@ if (isset($_GET["qc_statuses"])) {$qc_statuses=$_GET["qc_statuses"];} elseif (isset($_POST["qc_statuses"])) {$qc_statuses=$_POST["qc_statuses"];} if (isset($_GET["qc_lists"])) {$qc_lists=$_GET["qc_lists"];} elseif (isset($_POST["qc_lists"])) {$qc_lists=$_POST["qc_lists"];} +if (isset($_GET["qc_statuses"])) {$qc_statuses=$_GET["qc_statuses"];} + elseif (isset($_POST["qc_statuses"])) {$qc_statuses=$_POST["qc_statuses"];} +if (isset($_GET["qc_statuses_id"])) {$qc_statuses_id=$_GET["qc_statuses_id"];} + elseif (isset($_POST["qc_statuses_id"])) {$qc_statuses_id=$_POST["qc_statuses_id"];} if (isset($_GET["qc_get_record_launch"])) {$qc_get_record_launch=$_GET["qc_get_record_launch"];} elseif (isset($_POST["qc_get_record_launch"])) {$qc_get_record_launch=$_POST["qc_get_record_launch"];} if (isset($_GET["qc_show_recording"])) {$qc_show_recording=$_GET["qc_show_recording"];} @@ -810,6 +820,8 @@ if (isset($_GET["qc_shift_id"])) {$qc_shift_id=$_GET["qc_shift_id"];} elseif (isset($_POST["qc_shift_id"])) {$qc_shift_id=$_POST["qc_shift_id"];} if (isset($_GET["qc_web_form_address"])) {$qc_web_form_address=$_GET["qc_web_form_address"];} elseif (isset($_POST["qc_web_form_address"])) {$qc_web_form_address=$_POST["qc_web_form_address"];} +if (isset($_GET["qc_scorecard_id"])) {$qc_scorecard_id=$_GET["qc_scorecard_id"];} + elseif (isset($_POST["qc_scorecard_id"])) {$qc_scorecard_id=$_POST["qc_scorecard_id"];} if (isset($_GET["qc_script"])) {$qc_script=$_GET["qc_script"];} elseif (isset($_POST["qc_script"])) {$qc_script=$_POST["qc_script"];} if (isset($_GET["ingroup_recording_override"])) {$ingroup_recording_override=$_GET["ingroup_recording_override"];} @@ -2577,7 +2589,7 @@ if (strlen($dial_status) > 0) ############################################# ##### START SYSTEM_SETTINGS LOOKUP ##### -$stmt = "SELECT use_non_latin,enable_queuemetrics_logging,enable_vtiger_integration,qc_features_active,outbound_autodial_active,sounds_central_control_active,enable_second_webform,user_territories_active,custom_fields_enabled,admin_web_directory,webphone_url,first_login_trigger,hosted_settings,default_phone_registration_password,default_phone_login_password,default_server_password,test_campaign_calls,active_voicemail_server,voicemail_timezones,default_voicemail_timezone,default_local_gmt,campaign_cid_areacodes_enabled,pllb_grouping_limit,did_ra_extensions_enabled,expanded_list_stats,contacts_enabled,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,call_menu_qualify_enabled,admin_list_counts,allow_voicemail_greeting,svn_revision,allow_emails,level_8_disable_add,pass_key,pass_hash_enabled,disable_auto_dial,country_code_list_stats,frozen_server_call_clear,active_modules,allow_chats,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_did_entry_list_id,enable_third_webform,default_language,user_hide_realtime_enabled,log_recording_access,alt_ivr_logging,admin_row_click,admin_screen_colors,ofcom_uk_drop_calc,agent_screen_colors,script_remove_js,manual_auto_next,user_new_lead_limit,agent_xfer_park_3way,agent_soundboards,web_loader_phone_length,agent_script,enable_auto_reports,enable_pause_code_limits,enable_drop_lists,allow_ip_lists,system_ip_blacklist,hide_inactive_lists,allow_manage_active_lists,expired_lists_inactive,did_system_filter,enable_gdpr_download_deletion,mute_recordings,user_admin_redirect,list_status_modification_confirmation,sip_event_logging,call_quota_lead_ranking,enable_second_script,enable_first_webform,recording_buttons,opensips_cid_name,require_password_length,user_account_emails,outbound_cid_any,entries_per_page,browser_call_alerts,inbound_answer_config,enable_international_dncs,daily_call_count_limit,allow_shared_dial,agent_search_method,admin_home_url FROM system_settings;"; +$stmt = "SELECT use_non_latin,enable_queuemetrics_logging,enable_vtiger_integration,qc_features_active,outbound_autodial_active,sounds_central_control_active,enable_second_webform,user_territories_active,custom_fields_enabled,admin_web_directory,webphone_url,first_login_trigger,hosted_settings,default_phone_registration_password,default_phone_login_password,default_server_password,test_campaign_calls,active_voicemail_server,voicemail_timezones,default_voicemail_timezone,default_local_gmt,campaign_cid_areacodes_enabled,pllb_grouping_limit,did_ra_extensions_enabled,expanded_list_stats,contacts_enabled,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,call_menu_qualify_enabled,admin_list_counts,allow_voicemail_greeting,svn_revision,allow_emails,level_8_disable_add,pass_key,pass_hash_enabled,disable_auto_dial,country_code_list_stats,frozen_server_call_clear,active_modules,allow_chats,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_did_entry_list_id,enable_third_webform,default_language,user_hide_realtime_enabled,log_recording_access,alt_ivr_logging,admin_row_click,admin_screen_colors,ofcom_uk_drop_calc,agent_screen_colors,script_remove_js,manual_auto_next,user_new_lead_limit,agent_xfer_park_3way,agent_soundboards,web_loader_phone_length,agent_script,enable_auto_reports,enable_pause_code_limits,enable_drop_lists,allow_ip_lists,system_ip_blacklist,hide_inactive_lists,allow_manage_active_lists,expired_lists_inactive,did_system_filter,enable_gdpr_download_deletion,mute_recordings,user_admin_redirect,list_status_modification_confirmation,sip_event_logging,call_quota_lead_ranking,enable_second_script,enable_first_webform,recording_buttons,opensips_cid_name,require_password_length,user_account_emails,outbound_cid_any,entries_per_page,browser_call_alerts,inbound_answer_config,enable_international_dncs,daily_call_count_limit,allow_shared_dial,agent_search_method,admin_home_url,qc_claim_limit,qc_expire_days FROM system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); if ($DB) {echo "$stmt\n";} $qm_conf_ct = mysqli_num_rows($rslt); @@ -2679,6 +2691,8 @@ if ($qm_conf_ct > 0) $SSallow_shared_dial = $row[92]; $SSagent_search_method = $row[93]; $SSadmin_home_url = $row[94]; + $SSqc_claim_limit = $row[95]; + $SSqc_expire_days = $row[96]; } ##### END SETTINGS LOOKUP ##### ########################################### @@ -3035,6 +3049,8 @@ $enable_international_dncs = preg_replace('/[^0-9]/','',$enable_international_dn $daily_call_count_limit = preg_replace('/[^0-9]/','',$daily_call_count_limit); $allow_shared_dial = preg_replace('/[^0-9]/','',$allow_shared_dial); $shared_dial_rank = preg_replace('/[^0-9]/','',$shared_dial_rank); +$qc_claim_limit = preg_replace('/[^0-9]/','',$qc_claim_limit); +$qc_expire_days = preg_replace('/[^0-9]/','',$qc_expire_days); $user_new_lead_limit = preg_replace('/[^-0-9]/','',$user_new_lead_limit); $drop_call_seconds = preg_replace('/[^-0-9]/','',$drop_call_seconds); @@ -3620,6 +3636,9 @@ if ($non_latin < 1) $inbound_after_hours_voicemail = preg_replace('/[^-_0-9a-zA-Z]/','',$inbound_after_hours_voicemail); $pause_max_exceptions = preg_replace('/[^-_0-9a-zA-Z]/','',$pause_max_exceptions); +### ALPHA-NUMERIC and underscore + $qc_statuses_id = preg_replace('/[^_0-9a-zA-Z]/','',$qc_statuses_id); + ### ALPHA-NUMERIC and underscore and dash and slash and dot $menu_timeout_prompt = preg_replace('/[^-\/\|\._0-9a-zA-Z]/','',$menu_timeout_prompt); $menu_invalid_prompt = preg_replace('/[^-\/\|\._0-9a-zA-Z]/','',$menu_invalid_prompt); @@ -5485,12 +5504,13 @@ if ($SSscript_remove_js > 0) # 210302-1032 - Changed Logout to auto-logout through AJAX, with redirect to Admin Home URL # 210304-1615 - Added User modify_leads = 5 option, for READONLY # 210305-2159 - Added Default Phone Fields, Changed CLEAR LIST to remove custom fields for removed leads +# 210306-0840 - Added new QC module with QC scorecards, Quality Control Report, Settings Compare Utility # # make sure you have added a user to the vicidial_users MySQL table with at least user_level 9 to access this page the first time -$admin_version = '2.14-792a'; -$build = '210305-2159'; +$admin_version = '2.14-793a'; +$build = '210306-0840'; $STARTtime = date("U"); $SQLdate = date("Y-m-d H:i:s"); @@ -6288,7 +6308,7 @@ if ($ADD==31111111111111) {$hh='admin'; $sh='conference'; echo _QXZ("MODIFY AGEN if ($ADD==311111111111111) {$hh='admin'; $sh='settings'; echo _QXZ("MODIFY SYSTEM SETTINGS");} if ($ADD==321111111111111) {$hh='admin'; $sh='status'; echo _QXZ("MODIFY SYSTEM STATUSES");} if ($ADD==331111111111111) {$hh='admin'; $sh='status'; echo _QXZ("MODIFY STATUS CATEGORY");} -if ($ADD==341111111111111) {$hh='admin'; $sh='status'; echo _QXZ("MODIFY QC STATUS CODE");} +if ($ADD==341111111111111) {$hh='qc'; $sh='modify'; echo _QXZ("MODIFY QC STATUS CODE");} if ($ADD=="4A") {$hh='users'; $sh='list'; echo _QXZ("Modify User - Admin");} if ($ADD=="4B") {$hh='users'; $sh='list'; echo _QXZ("Modify User - Admin");} if ($ADD==4) {$hh='users'; $sh='list'; echo _QXZ("Modify User");} @@ -6486,7 +6506,7 @@ if ($ADD==196000000000) {$hh='admin'; $sh='cg'; echo _QXZ("CID GROUP LIST");} if ($ADD==197000000000) {$hh='admin'; $sh='vmmg'; echo _QXZ("VM MESSAGE GROUPS LIST");} if ($ADD==1000000000000) {$hh='admin'; $sh='conference'; echo _QXZ("CONFERENCE LIST");} if ($ADD==10000000000000) {$hh='admin'; $sh='conference'; echo _QXZ("AGENT CONFERENCE LIST");} -if ($ADD==100000000000000) {$hh='qc'; $sh='list'; echo _QXZ("Quality Control");} +if ($ADD==100000000000000) {$hh='qc'; $sh='campaign'; echo _QXZ("Quality Control");} if ($ADD==881) {$hh='qc'; $sh='enter'; echo _QXZ("Quality Control Campaign")," $campaign_id";} if ($ADD==550) {$hh='users'; $sh='search'; echo _QXZ("Search Form");} if ($ADD==551) {$hh='users'; echo _QXZ("SEARCH PHONES");} @@ -9789,7 +9809,6 @@ if ($ADD==11111111111) } ##### END ID override optional section ##### - echo "\n"; echo "
\n"; echo "\"Phones\" "; @@ -10566,6 +10585,7 @@ if ($ADD==192111111111) + $NWB#settings_containers-container_type$NWE
"._QXZ("Admin User Group").": \n"; - echo "\n"; - echo "\n"; + echo "
\n"; - echo "\n"; - echo _QXZ("QC Enabled").": $NWB#campaigns-qc_enabled$NWE
"._QXZ("QC Statuses").":
$NWB#campaigns-qc_statuses$NWE
$qc_statuses_list
\n"; +# echo "\n"; +# echo "\n"; +# echo "\n"; # echo "\n"; + echo "\n"; + echo "\n"; echo "\n"; echo "\n"; @@ -39805,7 +39956,7 @@ if ($ADD==311111111111111) $ALLagent_count = $rowx[2]; } - $stmt="SELECT version,install_date,use_non_latin,webroot_writable,enable_queuemetrics_logging,queuemetrics_server_ip,queuemetrics_dbname,queuemetrics_login,queuemetrics_pass,queuemetrics_url,queuemetrics_log_id,queuemetrics_eq_prepend,vicidial_agent_disable,allow_sipsak_messages,admin_home_url,enable_agc_xfer_log,db_schema_version,auto_user_add_value,timeclock_end_of_day,timeclock_last_reset_date,vdc_header_date_format,vdc_customer_date_format,vdc_header_phone_format,vdc_agent_api_active,qc_last_pull_time,enable_vtiger_integration,vtiger_server_ip,vtiger_dbname,vtiger_login,vtiger_pass,vtiger_url,qc_features_active,outbound_autodial_active,outbound_calls_per_second,enable_tts_integration,agentonly_callback_campaign_lock,sounds_central_control_active,sounds_web_server,sounds_web_directory,active_voicemail_server,auto_dial_limit,user_territories_active,allow_custom_dialplan,db_schema_update_date,enable_second_webform,default_webphone,default_external_server_ip,webphone_url,enable_agc_dispo_log,custom_dialplan_entry,queuemetrics_loginout,callcard_enabled,queuemetrics_callstatus,default_codecs,admin_web_directory,label_title,label_first_name,label_middle_initial,label_last_name,label_address1,label_address2,label_address3,label_city,label_state,label_province,label_postal_code,label_vendor_lead_code,label_gender,label_phone_number,label_phone_code,label_alt_phone,label_security_phrase,label_email,label_comments,custom_fields_enabled,slave_db_server,reports_use_slave_db,webphone_systemkey,first_login_trigger,default_phone_registration_password,default_phone_login_password,default_server_password,admin_modify_refresh,nocache_admin,generate_cross_server_exten,queuemetrics_addmember_enabled,queuemetrics_dispo_pause,label_hide_field_logs,queuemetrics_pe_phone_append,test_campaign_calls,agents_calls_reset,default_voicemail_timezone,default_local_gmt,noanswer_log,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,did_agent_log,campaign_cid_areacodes_enabled,pllb_grouping_limit,did_ra_extensions_enabled,expanded_list_stats,contacts_enabled,call_menu_qualify_enabled,admin_list_counts,allow_voicemail_greeting,svn_revision,queuemetrics_socket,queuemetrics_socket_url,enhanced_disconnect_logging,allow_emails,level_8_disable_add,pass_hash_enabled,pass_key,pass_cost,disable_auto_dial,queuemetrics_record_hold,country_code_list_stats,reload_timestamp,queuemetrics_pause_type,frozen_server_call_clear,callback_time_24hour,allow_chats,chat_url,chat_timeout,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_did_entry_list_id,enable_third_webform,agent_debug_logging,default_language,agent_whisper_enabled,user_hide_realtime_enabled,usacan_phone_dialcode_fix,cache_carrier_stats_realtime,oldest_logs_date,log_recording_access,report_default_format,alt_ivr_logging,default_phone_code,admin_row_click,admin_screen_colors,ofcom_uk_drop_calc,agent_screen_colors,script_remove_js,manual_auto_next,user_new_lead_limit,agent_xfer_park_3way,rec_prompt_count,agent_soundboards,web_loader_phone_length,agent_script,agent_chat_screen_colors,enable_auto_reports,enable_pause_code_limits,enable_drop_lists,allow_ip_lists,system_ip_blacklist,agent_push_events,agent_push_url,hide_inactive_lists,allow_manage_active_lists,expired_lists_inactive,did_system_filter,anyone_callback_inactive_lists,enable_gdpr_download_deletion,source_id_display,agent_logout_link,manual_dial_validation,mute_recordings,user_admin_redirect,list_status_modification_confirmation,sip_event_logging,call_quota_lead_ranking,enable_second_script,enable_first_webform,recording_buttons,opensips_cid_name,require_password_length,user_account_emails,outbound_cid_any,entries_per_page,browser_call_alerts,queuemetrics_pausereason,inbound_answer_config,enable_international_dncs,web_loader_phone_strip,manual_dial_phone_strip,daily_call_count_limit,allow_shared_dial,agent_search_method,phone_defaults_container from system_settings;"; + $stmt="SELECT version,install_date,use_non_latin,webroot_writable,enable_queuemetrics_logging,queuemetrics_server_ip,queuemetrics_dbname,queuemetrics_login,queuemetrics_pass,queuemetrics_url,queuemetrics_log_id,queuemetrics_eq_prepend,vicidial_agent_disable,allow_sipsak_messages,admin_home_url,enable_agc_xfer_log,db_schema_version,auto_user_add_value,timeclock_end_of_day,timeclock_last_reset_date,vdc_header_date_format,vdc_customer_date_format,vdc_header_phone_format,vdc_agent_api_active,qc_last_pull_time,enable_vtiger_integration,vtiger_server_ip,vtiger_dbname,vtiger_login,vtiger_pass,vtiger_url,qc_features_active,outbound_autodial_active,outbound_calls_per_second,enable_tts_integration,agentonly_callback_campaign_lock,sounds_central_control_active,sounds_web_server,sounds_web_directory,active_voicemail_server,auto_dial_limit,user_territories_active,allow_custom_dialplan,db_schema_update_date,enable_second_webform,default_webphone,default_external_server_ip,webphone_url,enable_agc_dispo_log,custom_dialplan_entry,queuemetrics_loginout,callcard_enabled,queuemetrics_callstatus,default_codecs,admin_web_directory,label_title,label_first_name,label_middle_initial,label_last_name,label_address1,label_address2,label_address3,label_city,label_state,label_province,label_postal_code,label_vendor_lead_code,label_gender,label_phone_number,label_phone_code,label_alt_phone,label_security_phrase,label_email,label_comments,custom_fields_enabled,slave_db_server,reports_use_slave_db,webphone_systemkey,first_login_trigger,default_phone_registration_password,default_phone_login_password,default_server_password,admin_modify_refresh,nocache_admin,generate_cross_server_exten,queuemetrics_addmember_enabled,queuemetrics_dispo_pause,label_hide_field_logs,queuemetrics_pe_phone_append,test_campaign_calls,agents_calls_reset,default_voicemail_timezone,default_local_gmt,noanswer_log,alt_log_server_ip,alt_log_dbname,alt_log_login,alt_log_pass,tables_use_alt_log_db,did_agent_log,campaign_cid_areacodes_enabled,pllb_grouping_limit,did_ra_extensions_enabled,expanded_list_stats,contacts_enabled,call_menu_qualify_enabled,admin_list_counts,allow_voicemail_greeting,svn_revision,queuemetrics_socket,queuemetrics_socket_url,enhanced_disconnect_logging,allow_emails,level_8_disable_add,pass_hash_enabled,pass_key,pass_cost,disable_auto_dial,queuemetrics_record_hold,country_code_list_stats,reload_timestamp,queuemetrics_pause_type,frozen_server_call_clear,callback_time_24hour,allow_chats,chat_url,chat_timeout,enable_languages,language_method,meetme_enter_login_filename,meetme_enter_leave3way_filename,enable_did_entry_list_id,enable_third_webform,agent_debug_logging,default_language,agent_whisper_enabled,user_hide_realtime_enabled,usacan_phone_dialcode_fix,cache_carrier_stats_realtime,oldest_logs_date,log_recording_access,report_default_format,alt_ivr_logging,default_phone_code,admin_row_click,admin_screen_colors,ofcom_uk_drop_calc,agent_screen_colors,script_remove_js,manual_auto_next,user_new_lead_limit,agent_xfer_park_3way,rec_prompt_count,agent_soundboards,web_loader_phone_length,agent_script,agent_chat_screen_colors,enable_auto_reports,enable_pause_code_limits,enable_drop_lists,allow_ip_lists,system_ip_blacklist,agent_push_events,agent_push_url,hide_inactive_lists,allow_manage_active_lists,expired_lists_inactive,did_system_filter,anyone_callback_inactive_lists,enable_gdpr_download_deletion,source_id_display,agent_logout_link,manual_dial_validation,mute_recordings,user_admin_redirect,list_status_modification_confirmation,sip_event_logging,call_quota_lead_ranking,enable_second_script,enable_first_webform,recording_buttons,opensips_cid_name,require_password_length,user_account_emails,outbound_cid_any,entries_per_page,browser_call_alerts,queuemetrics_pausereason,inbound_answer_config,enable_international_dncs,web_loader_phone_strip,manual_dial_phone_strip,daily_call_count_limit,allow_shared_dial,agent_search_method,phone_defaults_container,qc_claim_limit,qc_expire_days from system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); $row=mysqli_fetch_row($rslt); $version = $row[0]; @@ -40004,6 +40155,8 @@ if ($ADD==311111111111111) $allow_shared_dial = $row[193]; $agent_search_method = $row[194]; $phone_defaults_container = $row[195]; + $qc_claim_limit = $row[196]; + $qc_expire_days = $row[197]; if ($pass_hash_enabled > 0) {$pass_hash_enabled = 'ENABLED';} else {$pass_hash_enabled = 'DISABLED';} @@ -40595,6 +40748,8 @@ if ($ADD==311111111111111) echo "$NWB#settings-agent_chat_screen_colors$NWE\n"; echo "\n"; + echo "\n"; + echo "\n"; echo "\n"; echo "\n"; @@ -43788,17 +43943,68 @@ if (($ADD==100000000000000) && ($qc_auth=='1')) echo "
"._QXZ("QC Enabled").": $NWB#campaigns-qc_enabled$NWE
"._QXZ("QC Statuses").":
$NWB#campaigns-qc_statuses$NWE
$qc_statuses_list
QC Lists:
$NWB#campaigns-qc_lists$NWE
$qc_lists_list
\n"; + echo ""._QXZ("QC Statuses").": $NWB#campaigns-qc_statuses_id$NWE
"._QXZ("QC Scorecard").": $NWB#campaigns-qc_scorecard$NWE
"._QXZ("QC WebForm").": $NWB#campaigns-qc_web_form_address$NWE
"._QXZ("QC Script").": \n"; echo "\n"; echo "\n"; - echo "
\n"; + echo "
\n"; echo "\n"; echo "\n"; echo "\n"; @@ -29567,6 +29627,49 @@ if ($ADD==311) echo "$status_groups_menu"; echo "$NWB#lists-status_group_id$NWE\n"; + if ($SSqc_features_active>0) + { + ##### get QC status container listings for pulldown + $stmt="SELECT container_id,container_notes from vicidial_settings_containers where container_type='QC_TEMPLATE' order by container_id;"; + $rslt=mysql_to_mysqli($stmt, $link); + $containers_to_print = mysqli_num_rows($rslt); + $QCcontainers_list=""; + $o=0; + while ($containers_to_print > $o) + { + $rowx=mysqli_fetch_row($rslt); + $QCcontainers_list .= "\n"; + $qc_containers_list["$rowx[0]"] = "$rowx[1]"; + $o++; + } + ##### get scorecards listings for pulldown + $stmt="SELECT qc_scorecard_id,scorecard_name from quality_control_scorecards where active='Y' order by qc_scorecard_id;"; + $rslt=mysql_to_mysqli($stmt, $link); + $scorecards_to_print = mysqli_num_rows($rslt); + $QCscorecards_list=""; + $o=0; + while ($scorecards_to_print > $o) + { + $rowx=mysqli_fetch_row($rslt); + $QCscorecards_list .= "\n"; + $scorecardname_list["$rowx[0]"] = "$rowx[1]"; + $o++; + } + + echo "\n"; + + echo "\n"; + + echo "\n"; + + } + echo "\n"; if ($SSenable_second_webform > 0) { @@ -30696,7 +30799,7 @@ if ($ADD==3111) echo "
"._QXZ("List ID").": $list_id$NWB#lists-list_id$NWE
"._QXZ("List Name").": $NWB#lists-list_name$NWE
"._QXZ("List Description").": $NWB#lists-list_description$NWE
"._QXZ("QC Statuses").": $NWB#lists-qc_statuses_id$NWE
"._QXZ("QC Scorecard Override").": $NWB#lists-qc_scorecard_override$NWE
"._QXZ("QC WebForm").": $NWB#lists-qc_web_form_address$NWE
"._QXZ("Web Form").": $NWB#lists-web_form_address$NWE"; if ($SSenable_first_webform < 1) {echo " "._QXZ("DISABLED")."";} echo "
\n"; - echo "\n"; + echo "\n"; +/* JCJ - deprecated 2021-03-06 ##### get status listings for dynamic pulldown $qc_statuses = preg_replace("/^ | -$/","",$qc_statuses); $QCstatuses = explode(" ", $qc_statuses); @@ -31865,7 +31971,33 @@ if ($ADD==3111) } $o++; } - +*/ + ##### get QC status container listings for pulldown + $stmt="SELECT container_id,container_notes from vicidial_settings_containers where container_type='QC_TEMPLATE' order by container_id;"; + $rslt=mysql_to_mysqli($stmt, $link); + $containers_to_print = mysqli_num_rows($rslt); + $QCcontainers_list=""; + $o=0; + while ($containers_to_print > $o) + { + $rowx=mysqli_fetch_row($rslt); + $QCcontainers_list .= "\n"; + $qc_containers_list["$rowx[0]"] = "$rowx[1]"; + $o++; + } + ##### get scorecards listings for pulldown + $stmt="SELECT qc_scorecard_id,scorecard_name from quality_control_scorecards where active='Y' order by qc_scorecard_id;"; + $rslt=mysql_to_mysqli($stmt, $link); + $scorecards_to_print = mysqli_num_rows($rslt); + $QCscorecards_list=""; + $o=0; + while ($scorecards_to_print > $o) + { + $rowx=mysqli_fetch_row($rslt); + $QCscorecards_list .= "\n"; + $scorecardname_list["$rowx[0]"] = "$rowx[1]"; + $o++; + } ##### get scripts listings for pulldown $stmt="SELECT script_id,script_name from vicidial_scripts $whereLOGadmin_viewable_groupsSQL order by script_id;"; $rslt=mysql_to_mysqli($stmt, $link); @@ -31893,9 +32025,21 @@ if ($ADD==3111) $o++; } - echo "\n"; - echo "\n"; - echo "\n"; + # echo "\n"; + # echo "\n"; + + echo "\n"; + + echo "\n"; + echo "\n"; + +/* JCJ - deprecated 2021-03-06 echo "\n"; echo "\n"; + echo "\n"; +*/ } + echo "\n"; + echo "\n"; + echo "\n"; + echo "
\n"; echo ""; - $stmt="SELECT 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,onhold_prompt_no_block,onhold_prompt_seconds,hold_time_option_no_block,hold_time_option_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,customer_chat_screen_colors,customer_chat_survey_link,customer_chat_survey_text,populate_lead_province,areacode_filter,areacode_filter_seconds,areacode_filter_action,areacode_filter_action_value,populate_state_areacode,inbound_survey,inbound_survey_filename,inbound_survey_accept_digit,inbound_survey_question_filename,inbound_survey_callmenu,icbq_expiration_hours,closing_time_action,closing_time_now_trigger,closing_time_filename,closing_time_end_filename,closing_time_lead_reset,closing_time_option_exten,closing_time_option_callmenu,closing_time_option_voicemail,closing_time_option_xfer_group,closing_time_option_callback_list_id,icbq_call_time_id,add_lead_timezone,icbq_dial_filter,populate_lead_source,populate_lead_vendor,park_file_name,waiting_call_url_on,waiting_call_url_off,enter_ingroup_url,cid_cb_confirm_number, cid_cb_invalid_filter_phone_group, cid_cb_valid_length, cid_cb_valid_filename, cid_cb_confirmed_filename, cid_cb_enter_filename, cid_cb_you_entered_filename, cid_cb_press_to_confirm_filename, cid_cb_invalid_filename, cid_cb_reenter_filename, cid_cb_error_filename,place_in_line_caller_number_filename,place_in_line_you_next_filename,ingroup_script_two,browser_alert_sound,browser_alert_volume,answer_signal,no_agent_delay,agent_search_method from vicidial_inbound_groups where group_id='$group_id' $LOGadmin_viewable_groupsSQL;"; + $stmt="SELECT 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,onhold_prompt_no_block,onhold_prompt_seconds,hold_time_option_no_block,hold_time_option_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,customer_chat_screen_colors,customer_chat_survey_link,customer_chat_survey_text,populate_lead_province,areacode_filter,areacode_filter_seconds,areacode_filter_action,areacode_filter_action_value,populate_state_areacode,inbound_survey,inbound_survey_filename,inbound_survey_accept_digit,inbound_survey_question_filename,inbound_survey_callmenu,icbq_expiration_hours,closing_time_action,closing_time_now_trigger,closing_time_filename,closing_time_end_filename,closing_time_lead_reset,closing_time_option_exten,closing_time_option_callmenu,closing_time_option_voicemail,closing_time_option_xfer_group,closing_time_option_callback_list_id,icbq_call_time_id,add_lead_timezone,icbq_dial_filter,populate_lead_source,populate_lead_vendor,park_file_name,waiting_call_url_on,waiting_call_url_off,enter_ingroup_url,cid_cb_confirm_number, cid_cb_invalid_filter_phone_group, cid_cb_valid_length, cid_cb_valid_filename, cid_cb_confirmed_filename, cid_cb_enter_filename, cid_cb_you_entered_filename, cid_cb_press_to_confirm_filename, cid_cb_invalid_filename, cid_cb_reenter_filename, cid_cb_error_filename,place_in_line_caller_number_filename,place_in_line_you_next_filename,ingroup_script_two,browser_alert_sound,browser_alert_volume,answer_signal,no_agent_delay,agent_search_method,qc_scorecard_id,qc_statuses_id from vicidial_inbound_groups where group_id='$group_id' $LOGadmin_viewable_groupsSQL;"; $rslt=mysql_to_mysqli($stmt, $link); $row=mysqli_fetch_row($rslt); @@ -30877,6 +30980,8 @@ if ($ADD==3111) $answer_signal = $row[174]; $no_agent_delay = $row[175]; $agent_search_method = $row[176]; + $qc_scorecard_id = $row[177]; + $qc_statuses_id = $row[178]; ##### get callmenu listings for dynamic pulldown $stmt="SELECT menu_id,menu_name from vicidial_call_menu $whereLOGadmin_viewable_groupsSQL order by menu_id;"; @@ -31811,8 +31916,9 @@ if ($ADD==3111) if ($SSqc_features_active > 0) { echo "
 
"._QXZ("Inbound Group QC Settings").":
"._QXZ("Inbound Group QC Settings").":
"._QXZ("QC Enabled").": $NWB#inbound_groups-qc_enabled$NWE
"._QXZ("QC Statuses").":
$NWB#inbound_groups-qc_statuses$NWE
$qc_statuses_list
"._QXZ("QC WebForm").": $NWB#inbound_groups-qc_web_form_address$NWE
"._QXZ("QC Enabled").": $NWB#inbound_groups-qc_enabled$NWE
"._QXZ("QC Statuses").":
$NWB#inbound_groups-qc_statuses$NWE
$qc_statuses_list
"._QXZ("QC Statuses").": $NWB#inbound_groups-qc_statuses_id$NWE
"._QXZ("QC Scorecard").": $NWB#inbound_groups-qc_scorecard$NWE
"._QXZ("QC WebForm").": $NWB#inbound_groups-qc_web_form_address$NWE
"._QXZ("QC Script").":
"._QXZ("QC Get Record Launch").": $NWB#inbound_groups-qc_get_record_launch$NWE
"._QXZ("QC Show Recording").": $NWB#inbound_groups-qc_show_recording$NWE
 
\n"; echo "


\n"; @@ -38792,6 +38942,7 @@ if ($ADD==392111111111) + $NWB#settings_containers-container_type$NWE
"._QXZ("QC Features Active").": $NWB#settings-qc_features_active$NWE
"._QXZ("QC Claim Limit").": $NWB#settings-qc_claim_limit$NWE
"._QXZ("QC Expire Days").": $NWB#settings-qc_expire_days$NWE
"._QXZ("QC Last Pull Time").": $qc_last_pull_time
"._QXZ("Default Codecs").": $NWB#settings-default_codecs$NWE
\n"; echo ""; - $stmt="SELECT campaign_id,campaign_name,qc_statuses from vicidial_campaigns where active = 'Y' and qc_enabled='Y' $LOGqc_allowed_campaignsSQL order by campaign_name"; - $rslt=mysql_to_mysqli($stmt, $link); - $vicidialconf_to_print = mysqli_num_rows($rslt); echo "\"Quality "._QXZ("Quality Control Listings").":\n"; - echo "
\n"; - echo ""; - echo ""; - echo ""; - echo ""; - echo "\n"; + + if (!$qc_display_group_type) {$qc_display_group_type="CAMPAIGN";} + + if ($qc_display_group_type=="CAMPAIGN") + { + $stmt="SELECT campaign_id,campaign_name,qc_statuses_id from vicidial_campaigns where active = 'Y' and qc_statuses_id!='' and qc_scorecard_id!='' $LOGqc_allowed_campaignsSQL order by campaign_name"; + $rslt=mysql_to_mysqli($stmt, $link); + $vicidialconf_to_print = mysqli_num_rows($rslt); + + echo "

"._QXZ("Campaigns").":
"._QXZ("CAMPAIGN ID").""._QXZ("CAMPAIGN NAME").""._QXZ("QC STATUSES").""._QXZ("MODIFY")."
\n"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo "\n"; + + $count_column="campaign_id"; + } + else if ($qc_display_group_type=="INGROUP") + { + $stmt="SELECT group_id,group_name,qc_statuses_id from vicidial_inbound_groups where active = 'Y' and qc_statuses_id!='' and qc_scorecard_id!='' $LOGqc_allowed_campaignsSQL order by group_id"; + $rslt=mysql_to_mysqli($stmt, $link); + $vicidialconf_to_print = mysqli_num_rows($rslt); + + echo "

"._QXZ("Ingroups").":
"._QXZ("CAMPAIGN ID").""._QXZ("CAMPAIGN NAME").""._QXZ("QC STATUSES").""._QXZ("QUALIFYING CALLS").""._QXZ("MODIFY")."
\n"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo "\n"; + + $count_column="group_id"; + } + else if ($qc_display_group_type=="LIST") + { + $stmt="SELECT list_id,list_name,qc_statuses_id from vicidial_lists where active = 'Y' and qc_statuses_id!='' and qc_scorecard_id!='' $LOGqc_allowed_campaignsSQL order by list_id"; + $rslt=mysql_to_mysqli($stmt, $link); + # echo $stmt; + $vicidialconf_to_print = mysqli_num_rows($rslt); + + echo "

"._QXZ("Lists").":
"._QXZ("GROUP ID").""._QXZ("GROUP NAME").""._QXZ("QC STATUSES").""._QXZ("QUALIFYING CALLS").""._QXZ("MODIFY")."
\n"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo "\n"; + + $count_column="list_id"; + } + + if ($vicidialconf_to_print==0) + { + echo ""; + } + + # $DB=1; + if ($DB) {echo "$qc_display_group_type|$stmt
";} $o=0; while ($vicidialconf_to_print > $o) @@ -43812,9 +44018,75 @@ if (($ADD==100000000000000) && ($qc_auth=='1')) { $bgcolor='class="records_list_y"'; } - echo " 0) {echo " onclick=\"window.document.location='$PHP_SELF?ADD=881&campaign_id=$row[0]'\"";} echo ">"; + + #$qc_statuses=explode(' ',$qc_status_list); + $qc_status_list=array(); + $qc_status_container_stmt="select container_entry from vicidial_settings_containers where container_id='$row[2]'"; + $qc_status_container_rslt=mysql_to_mysqli($qc_status_container_stmt, $link); + while ($qcsc_row=mysqli_fetch_row($qc_status_container_rslt)) + { + $container_text=preg_split('/\r|\n/', $qcsc_row[0]); + for ($q=0; $q0) + { + $qc_status_list=preg_split('/,/', $line); + break; + } + } + } + +# $qc_ct_stmt="select count(*) from vicidial_list inner join vicidial_lists on vicidial_list.list_id=vicidial_lists.list_id and status in ('".implode("','", $qc_statuses)."') where campaign_id='$row[0]'"; + + $total_qc_count=0; + # Campaign + if ($qc_display_group_type=="CAMPAIGN") + { + $qc_ct_stmt="select count(*) From vicidial_agent_log where campaign_id='$row[0]' and status in ('".implode("','", $qc_status_list)."') and event_time+INTERVAL (pause_sec+wait_sec) SECOND>=now()-INTERVAL $SSqc_expire_days DAY"; + if ($DB) {echo "|$qc_ct_stmt|
\n";} + $qc_ct_rslt=mysql_to_mysqli($qc_ct_stmt, $link); + $qc_ct_row=mysqli_fetch_row($qc_ct_rslt); + $total_qc_count=$qc_ct_row[0]; + } + + # List + if ($qc_display_group_type=="LIST") + { + $agent_log_stmt="select lead_id From vicidial_agent_log where status in ('".implode("','", $qc_status_list)."') and event_time+INTERVAL (pause_sec+wait_sec) SECOND>=now()-INTERVAL $SSqc_expire_days DAY"; + if ($DB) {echo "|$agent_log_stmt|
\n";} + $agent_log_rslt=mysql_to_mysqli($agent_log_stmt, $link); + while ($agent_log_row=mysqli_fetch_array($agent_log_rslt)) + { + $lead_id=$agent_log_row["lead_id"]; + $list_id_stmt="select count(*) from vicidial_list where list_id='$row[0]' and lead_id='$lead_id'"; + # if ($DB) {echo "|$list_id_stmt|
\n";} + $list_id_rslt=mysql_to_mysqli($list_id_stmt, $link); + $lid_row=mysqli_fetch_row($list_id_rslt); + $total_qc_count+=$lid_row[0]; + } + } + + # Ingroup + if ($qc_display_group_type=="INGROUP") + { + $qc_ct_stmt="select count(*) From vicidial_closer_log where campaign_id='$row[0]' and status in ('".implode("','", $qc_status_list)."') and call_date>=now()-INTERVAL $SSqc_expire_days DAY"; + if ($DB) {echo "|$qc_ct_stmt|
\n";} + $qc_ct_rslt=mysql_to_mysqli($qc_ct_stmt, $link); + $qc_ct_row=mysqli_fetch_row($qc_ct_rslt); + $total_qc_count=$qc_ct_row[0]; + } + + $qc_grabbed_stmt="select count(*) From quality_control_queue where $count_column='$row[0]' and status in ('".implode("','", $qc_status_list)."') and call_date>=now()-INTERVAL $SSqc_expire_days DAY"; + if ($DB) {echo "|$qc_grabbed_stmt|
\n";} + $qc_grabbed_rslt=mysql_to_mysqli($qc_grabbed_stmt, $link); + $qc_grabbed_row=mysqli_fetch_row($qc_grabbed_rslt); + $total_grabbed_count=$qc_grabbed_row[0]; + + echo "
0) {echo " onclick=\"window.document.location='$PHP_SELF?ADD=881&qc_display_group_type=$qc_display_group_type&$count_column=$row[0]'\"";} echo ">"; echo ""; - echo ""; + echo ""; + echo ""; echo "\n"; $o++; } @@ -43827,64 +44099,263 @@ if (($ADD==100000000000000) && ($qc_auth=='1')) ###################### if (($ADD==881) && ($qc_auth=='1')) { - echo "
"._QXZ("LIST ID").""._QXZ("LIST NAME").""._QXZ("QC STATUSES").""._QXZ("QUALIFYING CALLS").""._QXZ("MODIFY")."
*** "._QXZ("NO ".$qc_display_group_type."S CONFIGURED FOR QC")." ***
$row[0]
$row[0] $row[1] $row[2] ".implode(", ", $qc_status_list)." ".($total_qc_count-$total_grabbed_count+0).""._QXZ("MODIFY")."
\n"; - echo ""; - $stmt="SELECT campaign_id,campaign_name, qc_statuses from vicidial_campaigns where active = 'Y' and qc_enabled='Y' and campaign_id='$campaign_id' $LOGqc_allowed_campaignsSQL limit 1"; - $rslt=mysql_to_mysqli($stmt, $link); - $vicidialconf_to_print = mysqli_num_rows($rslt); - if ($vicidialconf_to_print > 0) + + if (!$qc_display_group_type) {$qc_display_group_type=="CAMPAIGN";} + + $referring_URL_string="&referring_section=$qc_display_group_type"; + switch($qc_display_group_type) { - $row=mysqli_fetch_row($rslt); - $qc_status_list=substr($row[2],0,strlen($row[2])-2); + case "CAMPAIGN": + $referring_URL_string.="&referring_element=$campaign_id"; + break; + case "LIST": + $referring_URL_string.="&referring_element=$list_id"; + break; + case "INGROUP": + $referring_URL_string.="&referring_element=$group_id"; + break; + } - echo "
$campaign_id - {$row[1]} - "._QXZ("Quality Control Queue")."
"._QXZ("QC statuses").": $qc_status_list\n"; + $qc_claim_stmt="select count(*) from quality_control_queue where qc_agent='$PHP_AUTH_USER' and qc_status='CLAIMED'"; # $LOGqc_allowed_campaignsSQL + if ($DB) {echo $qc_claim_stmt."
\n";} + $qc_claim_rslt=mysql_to_mysqli($qc_claim_stmt, $link); + $queue_ct_row=mysqli_fetch_row($qc_claim_rslt); - $qc_statuses=explode(' ',$qc_status_list); - echo "
\n"; - foreach ( $qc_statuses as $qc_status ) + echo ""; + # echo "
\n"; + + echo "
\n"; + + if ($queue_ct_row[0]>0) + { + echo ""; # #".$SSmenu_background." + echo ""; + echo ""; + echo ""; # #".$SSmenu_background." + echo ""; + echo ""; + echo ""; + echo ""; + echo "\n"; + $queue_stmt="select * from quality_control_queue where qc_agent='$PHP_AUTH_USER' and qc_status='CLAIMED' order by date_claimed"; + if ($DB) {echo $queue_stmt."
\n";} + $queue_rslt=mysql_to_mysqli($queue_stmt, $link); + $q=0; + while ($queue_row=mysqli_fetch_array($queue_rslt)) { - $stmt="SELECT lead_id,first_name,last_name,modify_date,user from vicidial_list inner join vicidial_lists on vicidial_list.list_id=vicidial_lists.list_id where campaign_id='$campaign_id' and status='$qc_status' order by status, modify_date"; - $rslt=mysql_to_mysqli($stmt, $link); - $vicidialconf_to_print = mysqli_num_rows($rslt); - $o=0; - while ($vicidialconf_to_print > $o) + $qc_id=$queue_row["qc_log_id"]; + $lead_id=$queue_row["lead_id"]; + $date_claimed=$queue_row["date_claimed"]; + $date_modified=$queue_row["date_modified"]; + $name_stmt="select concat(first_name, ' ', last_name) from vicidial_list where lead_id='$lead_id'"; + $name_rslt=mysql_to_mysqli($name_stmt, $link); + $name_row=mysqli_fetch_row($name_rslt); + $full_name=trim($name_row[0]); + + if (preg_match("/1$|3$|5$|7$|9$/i", $q)) { - if($o==0) + $bgcolor='class="records_list_x"'; + } + else + { + $bgcolor='class="records_list_y"'; + } + echo "
"; + echo ""; + echo ""; + echo ""; + echo ""; + echo "\n"; + $q++; + } + echo ""; # #".$SSmenu_background." + echo ""; + echo ""; + } + + + if ($queue_ct_row[0]<$SSqc_claim_limit) + { + + if ($qc_display_group_type=="CAMPAIGN") + { + $stmt="SELECT campaign_id,campaign_name, qc_statuses_id, 'CALL' as qc_display_method, qc_scorecard_id from vicidial_campaigns where active='Y' and qc_statuses_id!='' and qc_scorecard_id!='' and campaign_id='$campaign_id'"; + $campaign_clause=" and campaign_id='$campaign_id'"; # Used further down + $display_clause=" and campaign_id='$campaign_id'"; # Used further down + } + else if ($qc_display_group_type=="LIST") + { + $stmt="SELECT list_id,list_name, qc_statuses_id, 'CALL' as qc_display_method, qc_scorecard_id from vicidial_lists where active='Y' and qc_statuses_id!='' and qc_scorecard_id!='' and list_id='$list_id'"; + $campaign_clause=""; + $display_clause=" and list_id='$list_id'"; # Used further down + } + else if ($qc_display_group_type=="INGROUP") + { + $stmt="SELECT group_id,group_name, qc_statuses_id, 'CALL' as qc_display_method, qc_scorecard_id from vicidial_inbound_groups where active='Y' and qc_statuses_id!='' and qc_scorecard_id!='' and group_id='$group_id'"; + $campaign_clause=" and comments in ('CHAT', 'EMAIL', 'INBOUND')"; + $display_clause=" and comments in ('CHAT', 'EMAIL', 'INBOUND')"; # Used further down + } + + # $DB=1; + # $stmt="SELECT campaign_id,campaign_name, qc_statuses, 'LEAD' as qc_display_method, qc_scorecard_id from vicidial_campaigns where active = 'Y' and qc_enabled='Y' and campaign_id='$campaign_id' $LOGqc_allowed_campaignsSQL limit 1"; + if ($DB) {echo $stmt."
\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $vicidialconf_to_print = mysqli_num_rows($rslt); + if ($vicidialconf_to_print > 0) + { + $row=mysqli_fetch_row($rslt); + # $qc_status_list=substr($row[2],0,strlen($row[2])-2); + $qc_display_method=$row[3]; + $qc_scorecard_id=$row[4]; + + $qc_status_list=array(); + $qc_status_container_stmt="select container_entry from vicidial_settings_containers where container_id='$row[2]'"; + $qc_status_container_rslt=mysql_to_mysqli($qc_status_container_stmt, $link); + while ($qcsc_row=mysqli_fetch_row($qc_status_container_rslt)) + { + $container_text=preg_split('/\r|\n/', $qcsc_row[0]); + for ($q=0; $q"; - echo "
"; - echo ""; - echo ""; - echo ""; - echo "\n"; + $line=trim($container_text[$q]); + if (!preg_match('/^[\#|\;]/', $line) && strlen($line)>0) + { + $qc_status_list=preg_split('/,/', $line); + break; + } } - $row=mysqli_fetch_row($rslt); - if (preg_match("/1$|3$|5$|7$|9$/i", $o)) + } + + echo "
"._QXZ("$qc_display_group_type")." $row[0] - "._QXZ("Quality Control Queue")."
"._QXZ("QC statuses").": ".implode(", ", $qc_status_list)."


\n"; + + switch ($qc_sort_method) + { + case "STATUS": + $sort_clause_call="order by status, call_date"; + $sort_clause_lead="order by status, modify_date, last_local_call_time"; + break; + case "CALL_DATE": + $sort_clause_call="order by call_date, status"; + $sort_clause_lead="order by last_local_call_time, status, modify_date"; + break; + case "STATUS_DESC": + $sort_clause_call="order by status desc, call_date"; + $sort_clause_lead="order by status desc, modify_date, last_local_call_time"; + break; + case "CALL_DATE_DESC": + $sort_clause_call="order by call_date desc, status"; + $sort_clause_lead="order by last_local_call_time desc, status, modify_date desc"; + break; + } + + sort($qc_status_list); + foreach ( $qc_status_list as $qc_status ) + { + #if ($qc_display_method=="CALL") + # { + $stmt="select lead_id, agent_log_id, event_time+INTERVAL (wait_sec+pause_sec) SECOND as call_date, user, status, uniqueid from vicidial_agent_log where lead_id is not null and status='$qc_status' and event_time+INTERVAL (wait_sec+pause_sec) SECOND>=now()-INTERVAL $SSqc_expire_days DAY $campaign_clause $sort_clause_call"; + if ($DB) {echo $stmt."
\n";} + # } + #else + # { + # $stmt="SELECT lead_id,first_name,last_name,modify_date,user from vicidial_list inner join vicidial_lists on vicidial_list.list_id=vicidial_lists.list_id where campaign_id='$campaign_id' and status='$qc_status' order by status, modify_date $sort_clause_lead"; + # } + $rslt=mysql_to_mysqli($stmt, $link); + $vicidialconf_to_print = mysqli_num_rows($rslt); + $o=0; $q=0; + $prev_status=""; + while ($vicidialconf_to_print > $o) { - $bgcolor='class="records_list_x"'; + $row=mysqli_fetch_array($rslt); + $current_status=$row["status"]; + $lead_id=$row["lead_id"]; + $agent_log_id=$row["agent_log_id"]; + $uniqueid=$row["uniqueid"]; + $comments=$row["comments"]; + + # if ($qc_display_method=="CALL") {$display_clause="agent_log_id='$agent_log_id'";} else {$display_clause="lead_id='$lead_id'";} + + if ($qc_display_group_type=="LIST") + { + # Check if call belongs to selected list, otherwise skip + $followup_stmt="select count(*) From vicidial_list where lead_id='$lead_id' and list_id='$list_id'"; + $followup_rslt=mysql_to_mysqli($followup_stmt, $link); + $followup_row=mysqli_fetch_row($followup_rslt); + $matched_qc_record=$followup_row[0]; + } + else if ($qc_display_group_type=="INGROUP") + { + # Check if call came in on selected ingroup, otherwise skip + $followup_stmt="select count(*) From vicidial_closer_log where uniqueid='$uniqueid' and lead_id='$lead_id' and campaign_id='$group_id'"; + $followup_rslt=mysql_to_mysqli($followup_stmt, $link); + $followup_row=mysqli_fetch_row($followup_rslt); + $matched_qc_record=$followup_row[0]; + } + else + { + # Matching campaign was already established so no skip + $matched_qc_record=1; + } + + if(($prev_status!=$current_status && $qc_sort_method=="STATUS") || $o==0) + { + echo "
"; + echo ""; + echo ""; + echo ""; + echo ""; + echo "\n"; + } + if ($matched_qc_record) + { + # Only display records that are NOT in queue/claimed already. + $qc_check_stmt="select count(*) from quality_control_queue where agent_log_id='$agent_log_id'"; + # echo $qc_check_stmt; + $qc_check_rslt=mysql_to_mysqli($qc_check_stmt, $link); + $qc_check_row=mysqli_fetch_row($qc_check_rslt); + if($qc_check_row[0]==0) + { + $name_stmt="select concat(first_name, ' ', last_name) from vicidial_list where lead_id='$row[lead_id]'"; + $name_rslt=mysql_to_mysqli($name_stmt, $link); + $name_row=mysqli_fetch_row($name_rslt); + $lead_name=trim($name_row[0]); + + if (preg_match("/1$|3$|5$|7$|9$/i", $q)) + { + $bgcolor='class="records_list_x"'; + } + else + { + $bgcolor='class="records_list_y"'; + } + echo ""; + echo ""; + $lead_nameENC=urlencode($lead_name); + if (strlen($lead_name)<1) $lead_name='No Name'; + echo ""; + echo ""; + echo "\n"; + $q++; + } + + $prev_status=$row["status"]; + } + $o++; } - else - { - $bgcolor='class="records_list_y"'; - } - echo ""; - echo ""; - $lead_name=trim($row[1].' '.$row[2]); - $lead_nameENC=urlencode($lead_name); - if (strlen($lead_name)<1) $lead_name='No Name'; - echo ""; - echo ""; - echo "\n"; - $o++; + if ($DB) {echo $followup_stmt."
\n";} } } + else + { + echo ""._QXZ("ERROR: No QC")." "._QXZ(strtolower($qc_display_group_type))." "._QXZ("available").": $campaign_id$list_id$group_id

\n"; + } + + echo "
"._QXZ("YOUR CURRENT UNFINISHED QC CALLS")." ($queue_ct_row[0] "._QXZ("records").")
"._QXZ("QC ID").""._QXZ("LEAD ID").""._QXZ("NAME").""._QXZ("Date Claimed").""._QXZ("Date Modified")."
$qc_id $lead_id $full_name $date_claimed $date_modified
 
$qc_status ($vicidialconf_to_print)"._QXZ("LEAD ID").""._QXZ("NAME").""._QXZ("Last Modified").""._QXZ("UserID")."
$qc_status"._QXZ("LEAD ID").""._QXZ("NAME").""._QXZ("CALL DATE").""._QXZ("UserID")."
  $row[lead_id]$lead_name $row[call_date]$row[user]
  $row[0]$lead_name $row[3]$row[4]
\n"; } else { - echo _QXZ("ERROR: No QC campaign available:")."$campaign_id\n"; + echo "
\n"; + echo "
*** "._QXZ("You have too many QC calls to finish to claim any more")." ***\n"; # ($queue_ct_row[0] < $SSqc_claim_limit) } - - echo "
\n"; } @@ -44750,6 +45221,11 @@ if ($ADD==999999) if ( (preg_match("/CallCard Search/",$LOGallowed_reports)) or (preg_match("/ALL REPORTS/",$LOGallowed_reports)) ) {echo "
  • "._QXZ("CallCard Search")."\n";} } + if ($SSqc_features_active > 0) + { + if ( (preg_match("/Quality Control Report/",$LOGallowed_reports)) or (preg_match("/ALL REPORTS/",$LOGallowed_reports)) ) + {echo "
  • "._QXZ("Quality Control Report")."\n";} + } echo "\n"; @@ -45434,6 +45910,7 @@ if ($ADD==999994) echo "
  • "._QXZ("Old Help Page")."\n"; echo "
  • "._QXZ("Servers Versions")."\n"; echo "

    \n"; + echo "
  • "._QXZ("Settings Compare Utility")."\n"; echo "
  • "._QXZ("Campaign Debug Page")."\n"; echo "
  • "._QXZ("Shared Debug Page")."\n"; echo "
  • "._QXZ("Dial Log Report")."\n"; @@ -45874,9 +46351,74 @@ if ($ADD==999990) } } // End new voicemail box code - echo "
  • \n"; - echo "
    \n"; + if ($SSqc_features_active>0) + { + echo ""; + echo " "; # Padding + echo ""; + echo ""; + echo ""._QXZ("Quality Control stats").":"; + echo ""; + + echo ""; + echo "  "._QXZ("Campaign").""; + echo "  "._QXZ("Unclaimed Calls").""; + echo "  "._QXZ("In Review").""; + echo "  "._QXZ("Completed today").""; + echo ""; + + $stmt="SELECT campaign_id, qc_statuses from vicidial_campaigns where active = 'Y' and qc_enabled='Y' $LOGqc_allowed_campaignsSQL order by campaign_id"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $vicidialconf_to_print = mysqli_num_rows($rslt); + if ($vicidialconf_to_print > 0) + { + while ($row=mysqli_fetch_array($rslt)) + { + $campaign_id=$row[0]; + $qc_status_list=substr($row[1],0,strlen($row[1])-2); + $qc_statuses=explode(' ',$qc_status_list); + + $qc_ct_stmt="select count(*) from vicidial_list inner join vicidial_lists on vicidial_list.list_id=vicidial_lists.list_id and status in ('".implode("','", $qc_statuses)."') where campaign_id='$campaign_id'"; + if ($DB) {echo "|$qc_ct_stmt|\n";} + $qc_ct_rslt=mysql_to_mysqli($qc_ct_stmt, $link); + $qc_ct_row=mysqli_fetch_row($qc_ct_rslt); + $total_qc_count=$qc_ct_row[0]; + + $qc_inreview_stmt="select count(*) From quality_control_queue where campaign_id='$campaign_id' and qc_status='CLAIMED'"; + $qc_inreview_rslt=mysql_to_mysqli($qc_inreview_stmt, $link); + $qc_inreview_row=mysqli_fetch_row($qc_inreview_rslt); + $total_inreview_count=$qc_inreview_row[0]; + + $qc_finish_stmt="select count(*), sum(if(date_completed>date(now()), 1, 0)) From quality_control_queue where campaign_id='$campaign_id' and qc_status='FINISHED'"; + $qc_finish_rslt=mysql_to_mysqli($qc_finish_stmt, $link); + $qc_finish_row=mysqli_fetch_row($qc_finish_rslt); + $total_finish_count=$qc_finish_row[0]; + $today_finish_count=$qc_finish_row[1]; + + echo ""; + # echo "".$row["campaign_id"].""; + echo "".$campaign_id.":"; + echo "".($total_qc_count-$total_inreview_count-$total_finish_count+0).""; + echo "".($total_inreview_count+0).""; + echo "".($today_finish_count+0).""; + echo ""; + } + } + else + { + echo ""; + echo "*** "._QXZ("NO ACTIVITY FOR")." $today ***"; + echo ""; + } + + + } + + echo "\n"; + + echo "
    \n"; $today=date("Y-m-d"); $yesterday=date("Y-m-d", mktime(0,0,0,date("m"),date("d")-1,date("Y"))); diff --git a/agc_2-X/trunk/www/vicidial/admin_header.php b/agc_2-X/trunk/www/vicidial/admin_header.php index 322df903..5a2f1ed4 100644 --- a/agc_2-X/trunk/www/vicidial/admin_header.php +++ b/agc_2-X/trunk/www/vicidial/admin_header.php @@ -86,6 +86,7 @@ # 200508-1052 - Added copy_prev_cm_option() JS function # 201108-1232 - Added no_header option within short_header option # 210226-1547 - Added Copy Phone link +# 210306-0902 - Changes for new QC module # $stmt="SELECT admin_home_url,enable_tts_integration,callcard_enabled,custom_fields_enabled,allow_emails,level_8_disable_add,allow_chats,enable_languages,admin_row_click,admin_screen_colors,user_new_lead_limit,user_territories_active,qc_features_active,agent_soundboards,enable_drop_lists,allow_ip_lists from system_settings;"; @@ -1998,25 +1999,55 @@ if ($subcamp_font_size < 4) {$subcamp_font_size='11';} 25) { + $campaign_sh="CLASS=\"subhead_style\""; + $ingroup_sh="CLASS=\"subhead_style\""; $list_sh="CLASS=\"subhead_style\""; $enter_sh="CLASS=\"subhead_style\""; $modify_sh="CLASS=\"subhead_style\""; + $scorecard_sh="CLASS=\"subhead_style\""; + if($qc_display_group_type=="CAMPAIGN") {$sh="campaign";} + if($qc_display_group_type=="INGROUP") {$sh="ingroup";} + if($qc_display_group_type=="LIST") {$sh="list";} + #if($sh=="modify") {$sh="modify";} + if($qc_display_group_type=="SCORECARD") {$sh="scorecard";} + if(!$sh) {$sh="campaign";} + + if ($sh=='campaign') {$campaign_sh="CLASS=\"subhead_style_selected\"";} + if ($sh=='ingroup') {$ingroup_sh="CLASS=\"subhead_style_selected\"";} if ($sh=='list') {$list_sh="CLASS=\"subhead_style_selected\"";} if ($sh=='enter') {$enter_sh="CLASS=\"subhead_style_selected\"";} if ($sh=='modify') {$modify_sh="CLASS=\"subhead_style_selected\"";} + if ($sh=='scorecard') {$scorecard_sh="CLASS=\"subhead_style_selected\"";} ?> - 0) {echo " onclick=\"window.document.location='$ADMIN?ADD=100000000000000';\"";} ?>> + 0) {echo " onclick=\"window.document.location='$ADMIN?ADD=100000000000000&qc_display_group_type=CAMPAIGN';\"";} ?>>   - + + 0) {echo " onclick=\"window.document.location='$ADMIN?ADD=100000000000000&qc_display_group_type=LIST';\"";} ?>> +   + + + + 0) {echo " onclick=\"window.document.location='$ADMIN?ADD=100000000000000&qc_display_group_type=INGROUP';\"";} ?>> +   + + + + + 0) {echo " onclick=\"qc_scorecards.php';\"";} ?>> +   + + + 0) {echo " onclick=\"window.document.location='$ADMIN?ADD=341111111111111';\"";} ?>>   diff --git a/agc_2-X/trunk/www/vicidial/help_documentation.txt b/agc_2-X/trunk/www/vicidial/help_documentation.txt index 58a01878..9c5b08e1 100644 --- a/agc_2-X/trunk/www/vicidial/help_documentation.txt +++ b/agc_2-X/trunk/www/vicidial/help_documentation.txt @@ -1,4 +1,4 @@ -# version: 20210305232801 +# version: 20210306093301 users-user User ID This field is where you put the users ID number, can be up to 8 digits in length, Must be at least 2 characters in length. users-pass Password This field is where you put the users password. Must be at least 2 characters in length. A medium strength user password will be at least 10 characters in length, and a strong user password will be at least 20 characters in length and have letters as well as at least one number. It is recommended that you use a longer password if possible, stringing together several unrelated words with no spaces, and a number somewhere in the string. The maximum size of a password is 100 characters. users-force_change_password Force Change Password If this option is set to Y then the user will be prompted to change their password the next time they log in to the administration webpage or the agent screen. Default is N. @@ -404,6 +404,7 @@ lists-local_call_time Local Call Time This is a setting for this list only, lists-audit_comments Audit Comments This option allows comments to be moved to an audit table. No longer editable, but viewable along with the date-time-creator of each comment. Default is N. This is a part of the Quality Control Add-On. lists-agent_script_override Agent Script Override If this field is set, this will be the script that the agent sees on their screen instead of the campaign script when the lead is from this list. Default is not set. lists-qc_scorecard_override QC Scorecard Override This is the scorecard to be shown to the agent when evaluating a QC record. It will override any campaign setting, but ingroup QC settings still take top priority. +lists-qc_web_form_address QC WebForm Address This is the website address that a QC agent can go to when clicking on the WEBFORM link in the QC screen. lists-qc_statuses_id QC Statuses ID This area is where you select which "QC_TEMPLATE" settings container will be used to determine the call statuses that are eligible for QC evaluation in this list. This will override the campaign's "QC Statuses ID" setting if it is set, but not ingroups. lists-inbound_list_script_override Inbound Script Override If this field is set, this will be the script that the agent sees on their screen instead of the campaign script when the agent receives an inbound call and the lead is from this list. Default is not set. lists-inbound_drop_voicemail Inbound Drop Voicemail Override If an inbound call associated with this list drops while in an Inbound Group queue, this is the voicemail box the call will be sent to if the Drop Action is set to go to a voicemail box. @@ -1394,3 +1395,4 @@ lead_export_report-vlc_filter VLC Filter If enabled, you will be able to ha lead_export_report-export_fields Export Fields STANDARD will include all of the lead fields that agents normally have access to, EXTENDED will include the following extra lead fields: entry_date, called_count, last_local_call_time, modify_date, called_since_last_reset. NOTE: If you have selected to use Entry Date or DID Filtering, EXTENDED will be automaticaly used. lead_export_report-exclude_call_log_data Exclude Call Log Data If you only want to export lead data, and no log or user information associated with the leads, then set this option to YES, change the -Date Field- to Entry Date and select -Lists-, -Statuses- and a -Campaign-, even though the Campaign will be ignored. lead_export_report-search_archived_data Search Archived Data If you want to pull data from older leads and-or call logs that have been archived on your system, then you can select either or both of those options here. +settings_compare Settings Compare Utility This utility will allow you to compare the settings from two records in your system and see what settings are different between the two. Step 1, select the type of settings to compare, CAMPAIGNS, LISTS, IN-GROUPS, USERS, etc... Step 2, select the two entries that you want to compare. To start over, click the RESET link. diff --git a/agc_2-X/trunk/www/vicidial/qc_api.php b/agc_2-X/trunk/www/vicidial/qc_api.php index 46b99f00..e49f00ae 100644 --- a/agc_2-X/trunk/www/vicidial/qc_api.php +++ b/agc_2-X/trunk/www/vicidial/qc_api.php @@ -2,7 +2,7 @@ # qc_api.php # # Copyright (C) 2012 poundteam.com LICENSE: AGPLv2 -# Copyright (C) 2014 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2021 Matt Florell LICENSE: AGPLv2 # # This script is designed to allow API functions for QC applications, contributed by poundteam.com # @@ -15,10 +15,11 @@ # 141007-2120 - Finalized adding QXZ translation to all admin files # 141229-2015 - Added code for on-the-fly language translations display # 150626-2120 - Modified mysqli_error() to mysqli_connect_error() where appropriate +# 210306-1051 - Changes for new QC module # -$version = '2.10-7'; -$build = '150626-2120'; +$version = '2.14-8'; +$build = '210306-1051'; require("dbconnect_mysqli.php"); require("functions.php"); diff --git a/agc_2-X/trunk/www/vicidial/qc_call_client_iframe.php b/agc_2-X/trunk/www/vicidial/qc_call_client_iframe.php index 9b4ea772..0eed96ea 100644 --- a/agc_2-X/trunk/www/vicidial/qc_call_client_iframe.php +++ b/agc_2-X/trunk/www/vicidial/qc_call_client_iframe.php @@ -4,7 +4,7 @@ # ViciDial database administration modify lead in vicidial_list # # Copyright (C) 2012 poundteam.com LICENSE: AGPLv2 -# Copyright (C) 2017 Matt Florell LICENSE: AGPLv2 +# Copyright (C) 2021 Matt Florell LICENSE: AGPLv2 # # This script is designed to allow QC review and modification of leads, contributed by poundteam.com # @@ -17,6 +17,7 @@ # 141007-2156 - Finalized adding QXZ translation to all admin files # 141229-2013 - Added code for on-the-fly language translations display # 170409-1533 - Added IP List validation code +# 210306-1052 - Changes for new QC module # require("dbconnect_mysqli.php"); @@ -134,7 +135,7 @@ $NOW_TIME = date("Y-m-d H:i:s"); ############################################# ##### START SYSTEM_SETTINGS LOOKUP ##### -$stmt = "SELECT use_non_latin,custom_fields_enabled,enable_languages,language_method FROM system_settings;"; +$stmt = "SELECT use_non_latin,custom_fields_enabled,enable_languages,language_method,qc_features_active FROM system_settings;"; $rslt=mysql_to_mysqli($stmt, $link); if ($DB) {echo "$stmt\n";} $qm_conf_ct = mysqli_num_rows($rslt); @@ -145,6 +146,7 @@ if ($qm_conf_ct > 0) $custom_fields_enabled = $row[1]; $SSenable_languages = $row[2]; $SSlanguage_method = $row[3]; + $SSqc_features_active = $row[4]; } ##### END SETTINGS LOOKUP ##### ########################################### diff --git a/agc_2-X/trunk/www/vicidial/qc_modify_lead.php b/agc_2-X/trunk/www/vicidial/qc_modify_lead.php index 56c2c0d2..e971b106 100644 --- a/agc_2-X/trunk/www/vicidial/qc_modify_lead.php +++ b/agc_2-X/trunk/www/vicidial/qc_modify_lead.php @@ -29,6 +29,7 @@ # 170527-2252 - Fix for rare inbound logging issue #1017 # 171001-1110 - Added in-browser audio control, if recording access control is disabled # 210304-1650 - Added modify_leads=5 read-only option +# 210306-0854 - Redesign of QC module # require("dbconnect_mysqli.php"); @@ -67,6 +68,8 @@ if (isset($_GET["list_id"])) {$list_id=$_GET["list_id"];} elseif (isset($_POST["list_id"])) {$list_id=$_POST["list_id"];} if (isset($_GET["campaign_id"])) {$campaign_id=$_GET["campaign_id"];} elseif (isset($_POST["campaign_id"])) {$campaign_id=$_POST["campaign_id"];} +if (isset($_GET["group_id"])) {$group_id=$_GET["group_id"];} + elseif (isset($_POST["group_id"])) {$group_id=$_POST["group_id"];} if (isset($_GET["phone_code"])) {$phone_code=$_GET["phone_code"];} elseif (isset($_POST["phone_code"])) {$phone_code=$_POST["phone_code"];} if (isset($_GET["server_ip"])) {$server_ip=$_GET["server_ip"];} @@ -139,10 +142,47 @@ if (isset($_POST["appointment_date"])) {$appointment_date=$_POST["appointment_ elseif (isset($_GET["appointment_date"])) {$appointment_date=$_GET["appointment_date"];} if (isset($_POST["appointment_time"])) {$appointment_time=$_POST["appointment_time"];} elseif (isset($_GET["appointment_time"])) {$appointment_time=$_GET["appointment_time"];} +if (isset($_POST["claim_QC"])) {$claim_QC=$_POST["claim_QC"];} + elseif (isset($_GET["claim_QC"])) {$claim_QC=$_GET["claim_QC"];} +if (isset($_POST["qc_agent"])) {$qc_agent=$_POST["qc_agent"];} + elseif (isset($_GET["qc_agent"])) {$qc_agent=$_GET["qc_agent"];} +if (isset($_POST["qc_log_id"])) {$qc_log_id=$_POST["qc_log_id"];} + elseif (isset($_GET["qc_log_id"])) {$qc_log_id=$_GET["qc_log_id"];} +if (isset($_POST["qc_process_status"])) {$qc_process_status=$_POST["qc_process_status"];} + elseif (isset($_GET["qc_process_status"])) {$qc_process_status=$_GET["qc_process_status"];} +if (isset($_POST["finish_qc"])) {$finish_qc=$_POST["finish_qc"];} + elseif (isset($_GET["finish_qc"])) {$finish_qc=$_GET["finish_qc"];} +if (isset($_POST["qc_display_method"])) {$qc_display_method=$_POST["qc_display_method"];} + elseif (isset($_GET["qc_display_method"])) {$qc_display_method=$_GET["qc_display_method"];} +if (isset($_POST["qc_display_method"])) {$qc_display_method=$_POST["qc_display_method"];} + elseif (isset($_GET["qc_display_method"])) {$qc_display_method=$_GET["qc_display_method"];} +if (isset($_POST["qc_display_group_type"])) {$qc_display_group_type=$_POST["qc_display_group_type"];} + elseif (isset($_GET["qc_display_group_type"])) {$qc_display_group_type=$_GET["qc_display_group_type"];} +if (isset($_POST["qc_status"])) {$qc_status=$_POST["qc_status"];} + elseif (isset($_GET["qc_status"])) {$qc_status=$_GET["qc_status"];} +if (isset($_POST["agent_log_id"])) {$agent_log_id=$_POST["agent_log_id"];} + elseif (isset($_GET["agent_log_id"])) {$agent_log_id=$_GET["agent_log_id"];} +if (isset($_POST["referring_section"])) {$referring_section=$_POST["referring_section"];} + elseif (isset($_GET["referring_section"])) {$referring_section=$_GET["referring_section"];} +if (isset($_POST["referring_element"])) {$referring_element=$_POST["referring_element"];} + elseif (isset($_GET["referring_element"])) {$referring_element=$_GET["referring_element"];} $STARTtime = date("U"); $defaultappointment = date("Y-m-d"); $NOW_TIME = date("Y-m-d H:i:s"); +$back_link="./admin.php?ADD=881&qc_display_group_type=$referring_section"; +switch($referring_section) # was $scorecard_source + { + case "CAMPAIGN": + $back_link.="&campaign_id=$referring_element"; + break; + case "LIST": + $back_link.="&list_id=$referring_element"; + break; + case "INGROUP": + $back_link.="&group_id=$referring_element"; + break; + } ############################################# ##### START SYSTEM_SETTINGS LOOKUP ##### @@ -190,6 +230,12 @@ $VUselected_language = $rights_row[5]; if (strlen($phone_number)<6) {$phone_number=$old_phone;} +require("screen_colors.php"); + +$Mhead_color = $SSstd_row5_background; +$Mmain_bgcolor = $SSmenu_background; +$Mhead_color = $SSstd_row5_background; + $auth=0; $auth_message = user_authorization($PHP_AUTH_USER,$PHP_AUTH_PW,'QC',1,0); if ($auth_message == 'GOOD') @@ -218,6 +264,7 @@ if ($auth < 1) exit; } + # check their permissions #if ( $modify_leads < 1 ) # { @@ -232,6 +279,228 @@ if ( $qc_enabled < 1 ) exit; } + +if ($submit=="SUBMIT" && $auth==1) + { + $stmt="UPDATE vicidial_list set status='" . mysqli_real_escape_string($link, $status) . "',title='" . mysqli_real_escape_string($link, $title) . "',first_name='" . mysqli_real_escape_string($link, $first_name) . "',middle_initial='" . mysqli_real_escape_string($link, $middle_initial) . "',last_name='" . mysqli_real_escape_string($link, $last_name) . "',address1='" . mysqli_real_escape_string($link, $address1) . "',address2='" . mysqli_real_escape_string($link, $address2) . "',address3='" . mysqli_real_escape_string($link, $address3) . "',city='" . mysqli_real_escape_string($link, $city) . "',state='" . mysqli_real_escape_string($link, $state) . "',province='" . mysqli_real_escape_string($link, $province) . "',postal_code='" . mysqli_real_escape_string($link, $postal_code) . "',country_code='" . mysqli_real_escape_string($link, $country_code) . "',alt_phone='" . mysqli_real_escape_string($link, $alt_phone) . "',phone_number='$phone_number',phone_code='$phone_code',email='" . mysqli_real_escape_string($link, $email) . "',security_phrase='" . mysqli_real_escape_string($link, $security) . "',comments='" . mysqli_real_escape_string($link, $comments) . "',rank='" . mysqli_real_escape_string($link, $rank) . "',owner='" . mysqli_real_escape_string($link, $owner) . "' where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "'"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + } + + +if ($finish_qc && $qc_log_id && $qc_process_status && $qc_agent==$PHP_AUTH_USER) + { + $qc_queue_stmt="select * from quality_control_queue where qc_log_id='$qc_log_id'"; + $qc_queue_rslt=mysql_to_mysqli($qc_queue_stmt, $link); + $q=0; + while ($queue_row=mysqli_fetch_array($qc_queue_rslt)) + { + $scorecard_source=$queue_row["scorecard_source"]; + $campaign_id=$queue_row["campaign_id"]; + $group_id=$queue_row["group_id"]; + $list_id=$queue_row["list_id"]; + + $redirect_URL_str="&qc_display_group_type=$referring_section"; # was $scorecard_source + switch($referring_section) # was $scorecard_source + { + case "CAMPAIGN": + $redirect_URL_str.="&campaign_id=$referring_element"; + $display_ID=$campaign_id; + break; + case "LIST": + $redirect_URL_str.="&list_id=$referring_element"; + $display_ID=$list_id; + break; + case "INGROUP": + $redirect_URL_str.="&group_id=$referring_element"; + $display_ID=$group_id; + break; + } + } + + if ($qc_process_status=="RELEASE") + { + $del_stmt="delete from quality_control_queue where qc_log_id='$qc_log_id'"; + $del_rslt=mysqli_query($link, $del_stmt); + $del_stmt2="delete from quality_control_checkpoint_log where qc_log_id='$qc_log_id'"; + $del_rslt2=mysqli_query($link, $del_stmt2); + } + else + { + if ($lead_id) + { + $upd_lead_stmt="UPDATE vicidial_list set status='" . mysqli_real_escape_string($link, $status) . "' where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "'"; + $upd_lead_rslt=mysqli_query($link, $upd_lead_stmt); + } + else + { + echo _QXZ("Error. No lead ID"); + exit; + } + $upd_stmt="update quality_control_queue set qc_status='$qc_process_status', date_completed=now() where qc_log_id='$qc_log_id'"; + if ($DB) {echo "|$upd_stmt|\n";} + $upd_rslt=mysqli_query($link, $upd_stmt); + } + header("Location: ./admin.php?ADD=881$redirect_URL_str"); + } + +if ($claim_QC && $auth==1) + { + if ((!$qc_display_group_type) || ($qc_display_group_type=="CAMPAIGN" && !$campaign_id) || ($qc_display_group_type=="LIST" && !$list_id) || ($qc_display_group_type=="INGROUP" && !$group_id)) + { + echo _QXZ("Error. QC type is not defined or missing info")." ($qc_display_group_type => $campaign_id|$list_id|$group_id)"; + exit; + } + if ($qc_display_method) + { + $list_id=0; + if ($agent_log_id) {$alid_clause="and agent_log_id='$agent_log_id'";} + # Get specific agent log record related to selected call to ascertain the appropriate prioritization of the QC scorecards based on the call direction and list ID + $agent_log_stmt="select agent_log_id, user, user_group, campaign_id, uniqueid, event_time+INTERVAL(pause_sec+wait_sec) SECOND as call_time, if(comments='CHAT' or comments='EMAIL' or comments='INBOUND', 'INBOUND', 'OUTBOUND') as direction from vicidial_agent_log where lead_id='$lead_id' and status='$qc_status' $alid_clause order by agent_log_id desc limit 1"; + if ($DB) {echo $agent_log_stmt."
    ";} + # http://svn.eflo.net:40080/vicidial/qc_modify_lead.php?claim_QC=CLAIM&qc_display_method=LEAD&agent_log_id=&qc_status=NP&lead_id=813114&campaign_id=TESTCAMP&lead_name=Test+Lead+17917 + $agent_log_rslt=mysql_to_mysqli($agent_log_stmt, $link); + if (mysqli_num_rows($agent_log_rslt)>0) + { + $alog_row=mysqli_fetch_array($agent_log_rslt); + $agent_log_id=$alog_row["agent_log_id"]; + $user=$alog_row["user"]; + $user_group=$alog_row["user_group"]; + $campaign_id=$alog_row["campaign_id"]; + $uniqueid=$alog_row["uniqueid"]; + $direction=$alog_row["direction"]; + $call_time=$alog_row["call_time"]; + } + + switch($direction) + { + case "OUTBOUND": + $log_stmt="select list_id from vicidial_log where uniqueid='$uniqueid'"; + break; + case "INBOUND": + $log_stmt="select list_id, campaign_id from vicidial_closer_log where lead_id='$lead_id' and uniqueid='$uniqueid'".($group_id ? "and campaign_id='$group_id'" : ""); + break; + } + $list_scorecard_clause=""; + $ingroup_scorecard_clause=""; + $log_rslt=mysql_to_mysqli($log_stmt, $link); + while($log_row=mysqli_fetch_array($log_rslt)) + { + # Both outbound and inbound calls have a list ID, list ID takes priority over outbound campaign, but not ingroup + $list_id=$log_row["list_id"]; + $list_scorecard_clause="UNION select qc_scorecard_id, 'LIST' as scorecard_source, qc_web_form_address, if(qc_scorecard_id!='', 2, 200) as priority from vicidial_lists where list_id='$list_id'"; + + # Inbound calls' QC scorecard takes priority over list ID and campaign ID. + if (!$group_id) {$group_id=$log_row["campaign_id"];} + if ($group_id) + { + $ingroup_scorecard_clause="UNION select qc_scorecard_id, 'INGROUP' as scorecard_source, qc_web_form_address, if(qc_scorecard_id!='', 1, 100) as priority from vicidial_inbound_groups where group_id='$group_id'"; + } + } + + # Get scorecard ID + $qc_scorecard_id=""; + $scorecard_stmt="select qc_scorecard_id, 'CAMPAIGN' as scorecard_source, qc_web_form_address, if(qc_scorecard_id!='', 3, 300) as priority from vicidial_campaigns where campaign_id='$campaign_id' $list_scorecard_clause $ingroup_scorecard_clause order by priority asc limit 1"; + + # echo $scorecard_stmt."
    "; + + $scorecard_rslt=mysql_to_mysqli($scorecard_stmt, $link); + while($scorecard_row=mysqli_fetch_array($scorecard_rslt)) + { + $qc_scorecard_id=$scorecard_row["qc_scorecard_id"]; + $scorecard_source=$scorecard_row["scorecard_source"]; + $qc_web_form_address=$scorecard_row["qc_web_form_address"]; + } + if (!$qc_scorecard_id) + { + echo _QXZ("Can't claim this - no QC scorecard found")."\n"; + exit; + } + + # select the nearest recording_id based on timestamp. 'Nearest' can be in either direction from the call time (i.e. before or after). + $recording_id=''; + $rec_log_stmt="select recording_id, if(vicidial_id='$uniqueid', 1, 0) as priority, ABS(TIMESTAMPDIFF(SECOND, start_time, '$call_time')) as priority2 from recording_log where lead_id='$lead_id' order by priority desc, priority2 asc limit 1"; + $rec_log_rslt=mysql_to_mysqli($rec_log_stmt, $link); + while($rec_log_row=mysqli_fetch_array($rec_log_rslt)) + { + $recording_id=$rec_log_row["recording_id"]; + } + + $ins_stmt="insert into quality_control_queue(qc_display_method, lead_id, agent_log_id, user, user_group, campaign_id, group_id, list_id, vicidial_id, recording_id, qc_scorecard_id, qc_agent, qc_user_group, qc_status, date_claimed, scorecard_source, status, call_date, qc_web_form_address) VALUES('$qc_display_method', '$lead_id', '$agent_log_id', '$user', '$user_group', '$campaign_id', '$group_id', '$list_id', '$uniqueid', '$recording_id', '$qc_scorecard_id', '$PHP_AUTH_USER', '$LOGuser_group', 'CLAIMED', now(), '$scorecard_source', '$qc_status', '$call_time', '$qc_web_form_address')"; +# echo $ins_stmt."
    "; + $ins_rslt=mysql_to_mysqli($ins_stmt, $link); + $qc_log_id=mysqli_insert_id($link); + if (!$qc_log_id) {echo _QXZ("ERROR - INSERT INTO QUALITY CONTROL QUEUE FAILED!"); exit;} + if ($scorecard_source!=$qc_display_group_type) + { + $alert="
    WARNING: $scorecard_source setting overrides $qc_display_group_type - using scorecard $qc_scorecard_id"; + } + + + $checkpoint_log_stmt="select * from quality_control_checkpoints where qc_scorecard_id='$qc_scorecard_id' order by checkpoint_rank asc"; + $checkpoint_log_rslt=mysql_to_mysqli($checkpoint_log_stmt, $link); + while ($checkpoint_row=mysqli_fetch_array($checkpoint_log_rslt)) + { + $checkpoint_ins_stmt="insert into quality_control_checkpoint_log(qc_log_id, campaign_id, group_id, list_id, qc_scorecard_id, checkpoint_row_id, checkpoint_text, checkpoint_rank, checkpoint_points, checkpoint_points_earned) VALUES ('$qc_log_id', '$campaign_id', '$group_id', '$list_id', '$qc_scorecard_id', '$checkpoint_row[checkpoint_row_id]', '$checkpoint_row[checkpoint_text]', '$checkpoint_row[checkpoint_rank]', '$checkpoint_row[checkpoint_points]', '$checkpoint_row[checkpoint_points]')"; + $checkpoint_ins_rslt=mysql_to_mysqli($checkpoint_ins_stmt, $link); +# echo $checkpoint_ins_stmt."
    "; + } +#exit; + } + else + { + echo _QXZ("Can't claim this - there's no QC display method")."\n"; + exit; + } + + + } + +if (!$qc_log_id) + { + echo _QXZ("No QC record detected - exiting."); exit; + } +else + { + $qc_queue_stmt="select * from quality_control_queue where qc_log_id='$qc_log_id'"; + $qc_queue_rslt=mysql_to_mysqli($qc_queue_stmt, $link); + $q=0; + while ($queue_row=mysqli_fetch_array($qc_queue_rslt)) + { + $qc_id=$queue_row["qc_log_id"]; + $qc_agent=$queue_row["qc_agent"]; + $lead_id=$queue_row["lead_id"]; + $date_claimed=$queue_row["date_claimed"]; + $date_modified=$queue_row["date_modified"]; + $scorecard_source=$queue_row["scorecard_source"]; + $campaign_id=$queue_row["campaign_id"]; + $group_id=$queue_row["group_id"]; + $list_id=$queue_row["list_id"]; + $qc_webform=$queue_row['qc_web_form_address']; + + $redirect_URL_str="&qc_display_group_type=$scorecard_source"; + switch($scorecard_source) + { + case "CAMPAIGN": + $redirect_URL_str.="&campaign_id=$campaign_id"; + $display_ID=$campaign_id; + break; + case "LIST": + $redirect_URL_str.="&list_id=$list_id"; + $display_ID=$list_id; + break; + case "INGROUP": + $redirect_URL_str.="&group_id=$group_id"; + $display_ID=$group_id; + break; + } + } + } +if ($qc_log_id && $qc_agent!=$PHP_AUTH_USER) + { + echo "Access denied - you are not the agent who claimed this QC record."; exit; + } + $label_title = _QXZ("Title"); $label_first_name = _QXZ("First"); $label_middle_initial = _QXZ("MI"); @@ -352,23 +621,62 @@ while ($scvl_ct > $s) } ##### END vicidial_list FIELD LENGTH LOOKUP ##### + //Added by Poundteam for QC. Gather record data to display on page and prepopulate title and hrefs, etc. -$stmt="SELECT * from vicidial_list A inner join vicidial_lists B on A.list_id=B.list_id inner join vicidial_campaigns C on B.campaign_id=C.campaign_id left outer join vicidial_statuses D on A.status=D.status left outer join vicidial_qc_codes E on A.status=E.code where A.lead_id='$lead_id'"; -$rslt=mysql_to_mysqli($stmt, $link); -if (mysqli_num_rows ($rslt) < '1' ) - { - if($DB) { echo "$stmt\n"; } - exit(); - } -$row=mysqli_fetch_assoc($rslt); -$original_record = $row; -$campaign_id = $row['campaign_id']; -$campaign_name = $row['campaign_name']; -$phone_number = $row['phone_number']; -$phone_code = $row['phone_code']; +#$stmt="SELECT * from vicidial_list A inner join vicidial_lists B on A.list_id=B.list_id inner join vicidial_campaigns C on B.campaign_id=C.campaign_id left outer join vicidial_statuses D on A.status=D.status left outer join vicidial_qc_codes E on A.status=E.code where A.lead_id='$lead_id'"; +#$rslt=mysql_to_mysqli($stmt, $link); +#if (mysqli_num_rows ($rslt) < '1' ) +# { +# if($DB) { echo "$stmt\n"; } +# exit(); +# } +#$row=mysqli_fetch_assoc($rslt); +#$original_record = $row; +#$campaign_id = $row['campaign_id']; +#$campaign_name = $row['campaign_name']; +#$phone_number = $row['phone_number']; +#$phone_code = $row['phone_code']; +#$scheduled_callback = $row['scheduled_callback']; + +##### grab vicidial_list data for lead ##### +$lead_stmt="SELECT lead_id,entry_date,modify_date,status,user,vendor_lead_code,source_id,list_id,gmt_offset_now,called_since_last_reset,phone_code,phone_number,title,first_name,middle_initial,last_name,address1,address2,address3,city,state,province,postal_code,country_code,gender,date_of_birth,alt_phone,email,security_phrase,comments,called_count,last_local_call_time,rank,owner,entry_list_id from vicidial_list where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "'"; +$lead_rslt=mysql_to_mysqli($lead_stmt, $link); +if ($DB) {echo "$stmt\n";} +$row=mysqli_fetch_array($lead_rslt); +if (strlen($row[0]) > 0) + {$lead_id = $row[0];} +$modify_date = $row[2]; +$dispo = $row[3]; +$tsr = $row[4]; +$vendor_id = $row[5]; +$list_id = $row[7]; +$gmt_offset_now = $row[8]; +$phone_code = $row[10]; +$phone_number = $row[11]; +$title = $row[12]; +$first_name = $row[13]; +$middle_initial = $row[14]; +$last_name = $row[15]; +$address1 = $row[16]; +$address2 = $row[17]; +$address3 = $row[18]; +$city = $row[19]; +$state = $row[20]; +$province = $row[21]; +$postal_code = $row[22]; +$country_code = $row[23]; +$gender = $row[24]; +$date_of_birth = $row[25]; +$alt_phone = $row[26]; +$email = $row[27]; +$security = $row[28]; +$comments = $row[29]; +$called_count = $row[30]; +$last_local_call_time = $row[31]; +$rank = $row[32]; +$owner = $row[33]; +$entry_list_id = $row[34]; $lead_name = trim(trim($row['first_name'].' '.$row['middle_initial']).' '.$row['last_name']); -$scheduled_callback = $row['scheduled_callback']; -$qc_webform = $row['qc_web_form_address']; ### BEGIN Replace variables with values for qc_webform ### $qc_webform = str_replace('--A--lead_id--B--', $row['lead_id'], $qc_webform); @@ -405,20 +713,316 @@ $qc_webform = str_replace('--A--current_user--B--', $PHP_AUTH_USER, $qc_webform) $qc_webform = str_replace('--A--called_count--B--', $row['called_count'], $qc_webform); ### END of replace variables code ### + $vdc_form_display = 'vdc_form_display.php'; if (preg_match("/cf_encrypt/",$active_modules)) {$vdc_form_display = 'vdc_form_display_encrypt.php';} -require("screen_colors.php"); ?> -<?php echo _QXZ("QC Modify Lead"); ?>: <?php echo "$lead_id - ".urldecode($lead_name).urldecode(" ("._QXZ("Campaign").": $campaign_id - $campaign_name)"); ?> +<?php echo _QXZ("QC Modify Lead"); ?>: <?php echo _QXZ("QC $scorecard_source")." $display_ID, $lead_id - ".urldecode($lead_name); ?> + + - + + + + + + "._QXZ("QC CAMPAIGN")." $campaign_id: "._QXZ("Lead")." $lead_id - ".urldecode($lead_name)."
    \n"; + +echo "\n"; +echo "\n"; + +echo "\n"; + +echo "\t\n"; +echo "\t\t\n"; +echo "\t\t\n"; +echo "\t\t\n"; +echo "\t\t\n"; +echo "\t\n"; + +echo "\n"; + + +echo ""; @@ -757,6 +1595,10 @@ else # echo "Close this window\n

    \n"; } + + #### START LOG RECORD GENERATION ##### + + ##### grab vicidial_log records ##### $stmt="select uniqueid,lead_id,list_id,campaign_id,call_date,start_epoch,end_epoch,length_in_sec,status,phone_code,phone_number,user,comments,processed,user_group,term_reason,alt_dial from vicidial_log where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "' order by uniqueid desc limit 500;"; $rslt=mysql_to_mysqli($stmt, $link); @@ -771,22 +1613,22 @@ else $row=mysqli_fetch_row($rslt); if (strlen($log_campaign)<1) {$log_campaign = $row[3];} if (preg_match("/1$|3$|5$|7$|9$/i", $u)) - {$bgcolor='bgcolor="#B9CBFD"';} + {$bgcolor="bgcolor='#".$SSstd_row2_background."'";} else - {$bgcolor='bgcolor="#9BB9FB"';} + {$bgcolor="bgcolor='#".$SSstd_row1_background."'";} $u++; - $call_log .= ""; - $call_log .= ""; - $call_log .= ""; - $call_log .= "\n"; - $call_log .= "\n"; - $call_log .= "\n"; - $call_log .= "\n"; - $call_log .= "\n"; - $call_log .= "\n"; - $call_log .= "\n"; - $call_log .= "\n"; + $call_log .= ""; + $call_log .= ""; + $call_log .= ""; + $call_log .= "\n"; + $call_log .= "\n"; + $call_log .= "\n"; + $call_log .= "\n"; + $call_log .= "\n"; + $call_log .= "\n"; + $call_log .= "\n"; + $call_log .= "\n"; $campaign_id = $row[3]; } @@ -804,30 +1646,31 @@ else $row=mysqli_fetch_row($rslt); if (strlen($Alog_campaign)<1) {$Alog_campaign = $row[5];} if (preg_match("/1$|3$|5$|7$|9$/i", $y)) - {$bgcolor='bgcolor="#B9CBFD"';} + {$bgcolor="bgcolor='#".$SSstd_row2_background."'";} else - {$bgcolor='bgcolor="#9BB9FB"';} + {$bgcolor="bgcolor='#".$SSstd_row1_background."'";} $y++; - $agent_log .= ""; - $agent_log .= ""; - $agent_log .= ""; - $agent_log .= "\n"; - $agent_log .= "\n"; - $agent_log .= "\n"; - $agent_log .= "\n"; - $agent_log .= "\n"; - $agent_log .= "\n"; - $agent_log .= "\n"; - $agent_log .= "\n"; - $agent_log .= "\n"; + $agent_log .= ""; + $agent_log .= ""; + $agent_log .= ""; + $agent_log .= "\n"; + $agent_log .= "\n"; + $agent_log .= "\n"; + $agent_log .= "\n"; + $agent_log .= "\n"; + $agent_log .= "\n"; + $agent_log .= "\n"; + $agent_log .= "\n"; + $agent_log .= "\n"; $campaign_id = $row[5]; } + ##### grab vicidial_qc_agent_log records ##### //Differentiate between View and Mod - $stmt="select * from vicidial_qc_agent_log where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "' order by qc_agent_log_id desc limit 100;"; + $stmt="select * from vicidial_qc_agent_log where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "' and view_epoch<'$STARTtime' order by qc_agent_log_id desc limit 100;"; $rslt=mysql_to_mysqli($stmt, $link); $Alogs_to_print = mysqli_num_rows($rslt); if($DB) echo "$stmt
    \n"; @@ -839,37 +1682,37 @@ else $row=mysqli_fetch_assoc($rslt); if (strlen($Alog_campaign)<1) {$Alog_campaign = $row[5];} if (preg_match("/1$|3$|5$|7$|9$/i", $y)) - {$bgcolor='bgcolor="#B9CBFD"';} + {$bgcolor="bgcolor='#".$SSstd_row2_background."'";} else - {$bgcolor='bgcolor="#9BB9FB"';} + {$bgcolor="bgcolor='#".$SSstd_row1_background."'";} $y++; if (strlen($row['save_epoch'])=='0') { //VIEW ONLY record - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; $qc_agent_log .= "\n"; } else { // CHANGE record $detailtooltip=str_replace("\n", " ", $row['details']); // tool tip line break and both work in IE, but not firefox. - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= ""; - $qc_agent_log .= "\n"; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= ""; + $qc_agent_log .= "\n"; } } @@ -886,73 +1729,42 @@ else $row=mysqli_fetch_row($rslt); if (strlen($Clog_campaign)<1) {$Clog_campaign = $row[3];} if (preg_match("/1$|3$|5$|7$|9$/i", $y)) - {$bgcolor='bgcolor="#B9CBFD"';} + {$bgcolor="bgcolor='#".$SSstd_row2_background."'";} else - {$bgcolor='bgcolor="#9BB9FB"';} + {$bgcolor="bgcolor='#".$SSstd_row1_background."'";} $y++; - $closer_log .= ""; - $closer_log .= ""; - $closer_log .= ""; - $closer_log .= "\n"; - $closer_log .= "\n"; - $closer_log .= "\n"; - $closer_log .= "\n"; - $closer_log .= "\n"; - $closer_log .= "\n"; - $closer_log .= "\n"; - $closer_log .= "\n"; + $closer_log .= ""; + $closer_log .= ""; + $closer_log .= ""; + $closer_log .= "\n"; + $closer_log .= "\n"; + $closer_log .= "\n"; + $closer_log .= "\n"; + $closer_log .= "\n"; + $closer_log .= "\n"; + $closer_log .= "\n"; + $closer_log .= "\n"; $campaign_id = $row[3]; } + #### END LOG RECORD GENERATION ##### - ##### grab vicidial_list data for lead ##### - $stmt="SELECT lead_id,entry_date,modify_date,status,user,vendor_lead_code,source_id,list_id,gmt_offset_now,called_since_last_reset,phone_code,phone_number,title,first_name,middle_initial,last_name,address1,address2,address3,city,state,province,postal_code,country_code,gender,date_of_birth,alt_phone,email,security_phrase,comments,called_count,last_local_call_time,rank,owner,entry_list_id from vicidial_list where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "'"; - $rslt=mysql_to_mysqli($stmt, $link); - if ($DB) {echo "$stmt\n";} - $row=mysqli_fetch_row($rslt); - if (strlen($row[0]) > 0) - {$lead_id = $row[0];} - $dispo = $row[3]; - $tsr = $row[4]; - $vendor_id = $row[5]; - $list_id = $row[7]; - $gmt_offset_now = $row[8]; - $phone_code = $row[10]; - $phone_number = $row[11]; - $title = $row[12]; - $first_name = $row[13]; - $middle_initial = $row[14]; - $last_name = $row[15]; - $address1 = $row[16]; - $address2 = $row[17]; - $address3 = $row[18]; - $city = $row[19]; - $state = $row[20]; - $province = $row[21]; - $postal_code = $row[22]; - $country_code = $row[23]; - $gender = $row[24]; - $date_of_birth = $row[25]; - $alt_phone = $row[26]; - $email = $row[27]; - $security = $row[28]; - $comments = $row[29]; - $called_count = $row[30]; - $last_local_call_time = $row[31]; - $rank = $row[32]; - $owner = $row[33]; - $entry_list_id = $row[34]; + + # JCJ - Lead information span + echo "\n\n
    "; if($DB) { echo __LINE__."\n"; } - echo "
    "._QXZ("Call information").": $first_name $last_name - $phone_number

    \n"; - echo "\n"; + echo "
    "._QXZ("Call information").": $first_name $last_name - $phone_number

    "; + echo "\n"; + echo "\n"; echo "\n"; - echo "\n"; - echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; echo "\n"; echo "\n"; echo "\n"; @@ -961,31 +1773,35 @@ else echo "\n"; echo "\n"; echo "\n"; - echo "
    "._QXZ("QC $scorecard_source")." $display_ID: "._QXZ("Lead")." $lead_id - ".urldecode($lead_name)."   GO BACK"; + +echo $alert; + +echo "
     
     
    \n"; + //end_call is set by submit button to denote "save", without it this is a VIEW, with it this is a SAVE + +$qc_master_span_visibility="block"; +$lead_information_span_visibility="none"; +$qc_call_information_visibility="none"; +$call_logs_span_visibility="none"; + if ($end_call > 0) { if ($LOGmodify_leads == '5') @@ -435,6 +1066,8 @@ if ($end_call > 0) echo "ERROR: "._QXZ("You do not have permission to modify leads").": $LOGmodify_leads \n"; exit; } + $qc_master_span_visibility="none"; + $lead_information_span_visibility="block"; if($DB) { echo __LINE__."\n"; } ### update the lead record in the vicidial_list table $stmt="UPDATE vicidial_list set status='" . mysqli_real_escape_string($link, $status) . "',title='" . mysqli_real_escape_string($link, $title) . "',first_name='" . mysqli_real_escape_string($link, $first_name) . "',middle_initial='" . mysqli_real_escape_string($link, $middle_initial) . "',last_name='" . mysqli_real_escape_string($link, $last_name) . "',address1='" . mysqli_real_escape_string($link, $address1) . "',address2='" . mysqli_real_escape_string($link, $address2) . "',address3='" . mysqli_real_escape_string($link, $address3) . "',city='" . mysqli_real_escape_string($link, $city) . "',state='" . mysqli_real_escape_string($link, $state) . "',province='" . mysqli_real_escape_string($link, $province) . "',postal_code='" . mysqli_real_escape_string($link, $postal_code) . "',country_code='" . mysqli_real_escape_string($link, $country_code) . "',alt_phone='" . mysqli_real_escape_string($link, $alt_phone) . "',phone_number='$phone_number',phone_code='$phone_code',email='" . mysqli_real_escape_string($link, $email) . "',security_phrase='" . mysqli_real_escape_string($link, $security) . "',comments='" . mysqli_real_escape_string($link, $comments) . "',rank='" . mysqli_real_escape_string($link, $rank) . "',owner='" . mysqli_real_escape_string($link, $owner) . "' where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "'"; @@ -659,7 +1292,13 @@ if ($end_call > 0) } else { - echo "\n"; + + + # JCJ - call span + echo "\n\n
    \n"; + echo _QXZ("PLACE A CALL TO LEAD").":

    \n"; + +/* JCJ - Commented out, moved to AJAX //Not a "Submit" result, viewing the record (possibly with URL options such as those below which modify callback status but not record data) if ($CBchangeUSERtoANY == 'YES') { @@ -701,18 +1340,21 @@ else echo "
    "._QXZ("vicidial_callback record changed to")." $appointment_date $appointment_time
    \n"; $qcchange='Y'; } - //QUALITY CONTROL LOGGING BEGIN - VIEW ONLY - //If no changes have been made, record "view" of this record. +*/ + + //QUALITY CONTROL LOGGING BEGIN - VIEW ONLY + //If no changes have been made, record "view" of this record. if ($qcchange != 'Y') { if($DB) echo __LINE__."\n QCCHANGE != Y"; ### insert a NEW record to the vicidial_closer_log table - $stmt="INSERT INTO vicidial_qc_agent_log (qc_user,qc_user_group,qc_user_ip,lead_user,web_server_ip,view_datetime,view_epoch,lead_id,list_id,campaign_id,processed) - values('" . mysqli_real_escape_string($link, $PHP_AUTH_USER) . "','$LOGuser_group','{$_SERVER['REMOTE_ADDR']}','{$original_record['user']}','{$_SERVER['SERVER_ADDR']}','$NOW_TIME','$STARTtime','" . mysqli_real_escape_string($link, $lead_id) . "','" . mysqli_real_escape_string($link, $original_record['list_id']) . "','" . mysqli_real_escape_string($link, $campaign_id) . "','N')"; + $stmt="INSERT INTO vicidial_qc_agent_log (qc_user,qc_user_group,qc_user_ip,lead_user,web_server_ip,view_datetime,view_epoch,lead_id,list_id,campaign_id,processed,qc_log_id) + values('" . mysqli_real_escape_string($link, $PHP_AUTH_USER) . "','$LOGuser_group','{$_SERVER['REMOTE_ADDR']}','{$original_record['user']}','{$_SERVER['SERVER_ADDR']}','$NOW_TIME','$STARTtime','" . mysqli_real_escape_string($link, $lead_id) . "','" . mysqli_real_escape_string($link, $original_record['list_id']) . "','" . mysqli_real_escape_string($link, $campaign_id) . "','N', '$qc_log_id')"; if ($DB) {echo "|$stmt|\n";} $rslt=mysql_to_mysqli($stmt, $link); } //QUALITY CONTROL LOGGING END + if($DB) echo __LINE__."\n"; $stmt="SELECT count(*) from vicidial_list where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "'"; $rslt=mysql_to_mysqli($stmt, $link); @@ -720,6 +1362,202 @@ else $row=mysqli_fetch_row($rslt); $lead_count = $row[0]; + ##### CALLBACK INFORMATION ##### + echo ""; + echo "
    "; + echo _QXZ("Callback Details").":
    "; + //Added scheduled_callback regular statuses option + if ( ($dispo == 'CALLBK') or ($dispo == 'CBHOLD') || $scheduled_callback=='Y' ) + { + if($DB) + { + echo __LINE__.""; + } + ### find any vicidial_callback records for this lead + $stmt="select callback_id,lead_id,list_id,campaign_id,status,entry_time,callback_time,modify_date,user,recipient,comments,user_group from vicidial_callbacks where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "' and status IN('ACTIVE','LIVE') order by callback_id desc LIMIT 1;"; + if ($DB) {echo "|$stmt|";} + $rslt=mysql_to_mysqli($stmt, $link); + $CB_to_print = mysqli_num_rows($rslt); + $rowx=mysqli_fetch_row($rslt); + + if ($CB_to_print>0) + { + ?> + + +
    :
    + > + + + + + +"; + echo ""; # + + echo ""; + echo ""; # + } + else + { + echo "
    "; # + echo ""; # + } + + $appointment_datetimeARRAY = explode(" ",$rowx[6]); + $appointment_date = $appointment_datetimeARRAY[0]; + $appointment_timeARRAY = explode(":",$appointment_datetimeARRAY[1]); + $appointment_hour = $appointment_timeARRAY[0]; + $appointment_min = $appointment_timeARRAY[1]; +?> + + + + + + + + + + + + +
    "; # + echo ""; + # echo ""; + # echo ""; + # echo ""; + echo _QXZ("New Callback Owner UserID").": "; + echo ""; + echo "
     "; #
    + echo ""; + # echo ""; + # echo ""; + # echo ""; + echo "
    "; + echo "
    "; + echo ""; + echo ""; + echo ""; + echo ""; + echo _QXZ("New Callback Owner UserID").": "; + echo "

    : + + +     + + : + + +
    + : + + + +
    + + + + " name=smt id=smt onClick="ChangeCallbackDateTime(this.form.callback_id.value)"> +
    + + + "._QXZ("No Callback records found")."
    "; + } + } + else + { + if($DB) + { + echo __LINE__.""; + } + //Modifed text to allow for other than CBHOLD via custom statuses with scheduled callback chosen + echo "
    "._QXZ("If you want to change this lead to a scheduled callback, first change the Disposition to CBHOLD or similar, then submit and you will be able to set the callback date and time.")."
    "; + } + echo "
    "; + echo "
    "; + ################################ + # JCJ - end call span + + + if ($lead_count > 0) { if($DB) echo __LINE__."\n"; @@ -738,9 +1576,9 @@ else } $row=mysqli_fetch_row($rslt); if (preg_match("/1$|3$|5$|7$|9$/i", $c)) - {$bgcolor='bgcolor="#B9CBFD"';} + {$bgcolor="bgcolor='#".$SSstd_row2_background."'";} else - {$bgcolor='bgcolor="#9BB9FB"';} + {$bgcolor="bgcolor='#".$SSstd_row1_background."'";} $c++; $alts_output .= "
    $u$row[4] $row[7] $row[8] $row[11] $row[3] $row[2] $row[1] $row[15]   $row[10]
    $u$row[4] $row[7] $row[8] $row[11] $row[3] $row[2] $row[1] $row[15]   $row[10]
    $y$row[3] $row[5] $row[1] $row[7] $row[9] $row[11] $row[13]   $row[14]   $row[15]   $row[17]
    $y$row[3] $row[5] $row[1] $row[7] $row[9] $row[11] $row[13]   $row[14]   $row[15]   $row[17]
    $y{$row['view_datetime']}"._QXZ("View Only - No changes")."{$row['qc_user']}{$row['lead_user']}{$row['campaign_id']}{$row['list_id']} 
    $y{$row['view_datetime']}"._QXZ("View Only - No changes")."{$row['qc_user']}{$row['lead_user']}{$row['campaign_id']}{$row['list_id']}  
    $y{$row['view_datetime']}{$row['old_status']}{$row['new_status']}{$row['qc_user']}{$row['lead_user']}{$row['campaign_id']}{$row['list_id']}{$row['elapsed_seconds']} DETAILS
    $y{$row['view_datetime']}{$row['old_status']}{$row['new_status']}{$row['qc_user']}{$row['lead_user']}{$row['campaign_id']}{$row['list_id']}".($row['elapsed_seconds']+0).""._QXZ("DETAILS")."
    $y$row[4] $row[7] $row[8] $row[11] $row[3] $row[2] $row[1]   $row[14]   $row[17]
    $y$row[4] $row[7] $row[8] $row[11] $row[3] $row[2] $row[1]   $row[14]   $row[17]
    \n"; - echo "\n"; - echo "\n"; + echo "\n"; + echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; + echo "
    $label_vendor_lead_code: $vendor_id     "._QXZ("Lead ID").": $lead_id
    "._QXZ("Fronter").": $tsr     "._QXZ("List ID").": $list_id     "._QXZ("Called Count").": $called_count
    $label_title:   \n"; - echo "$label_first_name:
    $label_middle_initial:   \n"; - echo " $label_last_name:
    $label_address1 :
    $label_address2 :
    $label_address3 :
    $label_city :
    $label_state:   \n"; - echo " $label_postal_code:
    \n"; + echo "\n"; + echo "\n"; + echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; $stmt="SELECT user_id, timestamp, list_id, campaign_id, comment from vicidial_comments where lead_id='$lead_id' order by timestamp"; $rslt=mysql_to_mysqli($stmt, $link); $row_count = mysqli_num_rows($rslt); @@ -998,16 +1814,18 @@ else echo "\n"; $comments=true; } - $rowx=mysqli_fetch_row($rslt); - echo "\n"; + $rowx=mysqli_fetch_row($rslt); + echo "\n"; $o++; } +/* JCJ - Removed, as it's on the scorecard now + if ($comments) { - echo "\n"; + # echo "\n"; } - echo "\n"; +*/ + // Section Modified for QC Functionality By PoundTeam // echo "\n"; // echo "\n"; // echo "\n"; - echo "\n"; +// echo "\n"; - echo "\n"; +// echo "\n"; echo "\n"; - echo "
    "._QXZ("Status").":     $dispo
    $label_vendor_lead_code: $vendor_id     "._QXZ("Lead ID").": $lead_id
    "._QXZ("Fronter").": $tsr     "._QXZ("List ID").": $list_id     "._QXZ("Called Count").": $called_count
    $label_province :
    Country :
    $label_phone_number :
    $label_phone_code :
    $label_alt_phone :
    $label_email :
    $label_security_phrase :
    Rank :
    Owner :
    $label_comments :
    $label_title:   \n"; + echo "$label_first_name:
    $label_middle_initial:   \n"; + echo " $label_last_name:
    $label_address1 :
    $label_address2 :
    $label_address3 :
    $label_city :
    $label_state:   \n"; + echo " $label_postal_code:
    $label_province :
    "._QXZ("Country")." :
    $label_phone_number :
    $label_phone_code :
    $label_alt_phone :
    $label_email :
    $label_security_phrase :
    "._QXZ("Rank")." :
    "._QXZ("Owner")." :
    $label_comments :
    "._QXZ("Comment History")."
    $rowx[0] :
    $rowx[1]
    "._QXZ("List ID").": $rowx[2]; "._QXZ("Campaign ID").": $rowx[3]
    $rowx[4]
    $rowx[0] :
    $rowx[1]
    "._QXZ("List ID").": $rowx[2]; "._QXZ("Campaign ID").": $rowx[3]
    $rowx[4]


    "._QXZ("QC Result").":
    "._QXZ("QC Result").": ("._QXZ("with")." $list_campaign "._QXZ("statuses").")
    Modify vicidial log
    Modify agent log
    Modify closer log
    "._QXZ("Disable QC log entry")." ("._QXZ("this feature is not active yet").")
    "._QXZ("Disable QC log entry")." ("._QXZ("this feature is not active yet").")
    "; if (strlen($qc_webform) > 4) { - echo ""._QXZ("QC Webform")."\n"; - } - echo "
    \n"; - echo "


    \n"; - - echo "
    \n"; - echo _QXZ("Callback Details").":
    \n"; - //Added scheduled_callback regular statuses option - if ( ($dispo == 'CALLBK') or ($dispo == 'CBHOLD') || $scheduled_callback=='Y' ) - { - if($DB) - { - echo __LINE__."\n"; - } - ### find any vicidial_callback records for this lead - $stmt="select callback_id,lead_id,list_id,campaign_id,status,entry_time,callback_time,modify_date,user,recipient,comments,user_group from vicidial_callbacks where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "' and status IN('ACTIVE','LIVE') order by callback_id desc LIMIT 1;"; - if ($DB) {echo "|$stmt|\n";} - $rslt=mysql_to_mysqli($stmt, $link); - $CB_to_print = mysqli_num_rows($rslt); - $rowx=mysqli_fetch_row($rslt); - - if ($CB_to_print>0) - { - if ($rowx[9] == 'USERONLY') - { - echo "
    \n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "

    \n"; - - echo "
    \n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo _QXZ("New Callback Owner UserID").": \n"; - echo "

    \n"; - } - else - { - echo "
    \n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo _QXZ("New Callback Owner UserID").": \n"; - echo "

    \n"; - } - - $appointment_datetimeARRAY = explode(" ",$rowx[6]); - $appointment_date = $appointment_datetimeARRAY[0]; - $appointment_timeARRAY = explode(":",$appointment_datetimeARRAY[1]); - $appointment_hour = $appointment_timeARRAY[0]; - $appointment_min = $appointment_timeARRAY[1]; - - ?> - -
    -
    :
    - - - - - - - - - - - - - -
    - > - - - - -
    : - - -     - - : - - -
    - : - - -
    - - - - " name=smt id=smt onClick="submit_form()"> -
    -
    - - "._QXZ("No Callback records found")."
    \n"; - } + echo ""._QXZ("QC Webform")."\n"; } else { - if($DB) - { - echo __LINE__."\n"; - } - //Modifed text to allow for other than CBHOLD via custom statuses with scheduled callback chosen - echo "
    "._QXZ("If you want to change this lead to a scheduled callback, first change the Disposition to CBHOLD or similar, then submit and you will be able to set the callback date and time.")."
    \n"; + echo " "; } - echo "
    \n"; - - echo "

    \n"; - - echo "
    \n"; + echo " \n"; + echo "\n"; if ($c > 0) { @@ -1281,7 +1917,7 @@ else { echo __LINE__."\n"; } - echo ""._QXZ("EXTENDED ALTERNATE PHONE NUMBERS FOR THIS LEAD").":\n"; + echo "
    "._QXZ("EXTENDED ALTERNATE PHONE NUMBERS FOR THIS LEAD").":\n"; echo "\n"; echo "\n"; @@ -1291,9 +1927,8 @@ else echo "

    \n"; } - - ### iframe for custom fields display/editing + if ($custom_fields_enabled > 0) { $CLlist_id = $list_id; @@ -1316,52 +1951,264 @@ else $submit_buttonURL = '&submit_button=YES'; if ($LOGmodify_leads == '5') {$submit_buttonURL = '&submit_button=READONLY';} - echo ""._QXZ("CUSTOM FIELDS FOR THIS LEAD").":
    \n"; + echo ""._QXZ("CUSTOM FIELDS FOR THIS LEAD").":
    \n"; echo "\n"; echo "

    "; } } } + echo ""; + # JCJ - END LEAD INFO span + + + # JCJ - CALL LOG span + echo "\n\n
    "; - - echo ""._QXZ("CALLS TO THIS LEAD").":\n"; + echo ""._QXZ("QUALITY CONTROL LOG RECORDS FOR THIS LEAD").":\n"; echo "
    # "._QXZ("ALT PHONE")." "._QXZ("ALT NOTE")." "._QXZ("ALT COUNT")." "._QXZ("ACTIVE")."
    \n"; - echo "\n"; - - echo "$call_log\n"; - + echo "\n"; + echo "$qc_agent_log"; echo "
    # "._QXZ("DATE/TIME")." "._QXZ("LENGTH")." "._QXZ("STATUS")." "._QXZ("TSR")." "._QXZ("CAMPAIGN")." "._QXZ("LIST")." "._QXZ("LEAD")." "._QXZ("HANGUP REASON")." "._QXZ("PHONE")."
    # "._QXZ("DATE/TIME")." "._QXZ("OLD STATUS").""._QXZ("NEW STATUS").""._QXZ("QC USER").""._QXZ("AGENT").""._QXZ("CAMPAIGN").""._QXZ("LIST").""._QXZ("ELAPSED")." 
    \n"; - echo "

    \n"; + echo "

    \n\n"; - echo ""._QXZ("CLOSER RECORDS FOR THIS LEAD").":\n"; + echo ""._QXZ("CALLS TO THIS LEAD").":\n"; echo "\n"; - echo "\n"; - - echo "$closer_log\n"; - - echo "
    # "._QXZ("DATE/TIME")." "._QXZ("LENGTH")." "._QXZ("STATUS")." "._QXZ("TSR")." "._QXZ("CAMPAIGN")." "._QXZ("LIST")." "._QXZ("LEAD")." "._QXZ("WAIT")." "._QXZ("HANGUP REASON")."
    \n"; - echo "

    \n"; - - - echo ""._QXZ("AGENT LOG RECORDS FOR THIS LEAD").":\n"; - echo "\n"; - echo "\n"; - - echo "$agent_log\n"; + echo "\n"; + echo "$call_log"; echo "
    # "._QXZ("DATE/TIME")." "._QXZ("CAMPAIGN")." "._QXZ("TSR")." "._QXZ("PAUSE")." "._QXZ("WAIT")." "._QXZ("TALK")." "._QXZ("DISPO")." "._QXZ("STATUS")." "._QXZ("GROUP")." "._QXZ("SUB")."
    # "._QXZ("DATE/TIME")." "._QXZ("LENGTH")." "._QXZ("STATUS")." "._QXZ("TSR")." "._QXZ("CAMPAIGN")." "._QXZ("LIST")." "._QXZ("LEAD")." "._QXZ("HANGUP REASON")." "._QXZ("PHONE")."
    \n"; - echo "

    \n"; - echo ""._QXZ("QUALITY CONTROL LOG RECORDS FOR THIS LEAD").":\n"; + echo "

    \n\n"; + + echo ""._QXZ("CLOSER RECORDS FOR THIS LEAD").":\n"; echo "\n"; - echo "\n"; - echo "$qc_agent_log\n"; + echo "\n"; + echo "$closer_log"; echo "
    # "._QXZ("DATE/TIME")." "._QXZ("OLD STATUS").""._QXZ("NEW STATUS").""._QXZ("QC USER").""._QXZ("AGENT").""._QXZ("CAMPAIGN").""._QXZ("LIST").""._QXZ("ELAPSED")." 
    # "._QXZ("DATE/TIME")." "._QXZ("LENGTH")." "._QXZ("STATUS")." "._QXZ("TSR")." "._QXZ("CAMPAIGN")." "._QXZ("LIST")." "._QXZ("LEAD")." "._QXZ("WAIT")." "._QXZ("HANGUP REASON")."
    \n"; - echo "

    \n"; + echo "

    \n\n"; - echo ""._QXZ("RECORDINGS FOR THIS LEAD").":\n"; - echo "\n"; - echo "\n"; - $stmt="select recording_id,channel,server_ip,extension,start_time,start_epoch,end_time,end_epoch,length_in_sec,length_in_min,filename,location,lead_id,user,vicidial_id from recording_log where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "' order by recording_id desc limit 500;"; + echo ""._QXZ("AGENT LOG RECORDS FOR THIS LEAD").":\n"; + echo "
    # "._QXZ("LEAD").""._QXZ("DATE/TIME")." "._QXZ("SECONDS")."   "._QXZ("RECID").""._QXZ("FILENAME").""._QXZ("LOCATION").""._QXZ("TSR")."
    \n"; + echo "\n"; + echo "$agent_log"; + echo "
    # "._QXZ("DATE/TIME")." "._QXZ("CAMPAIGN")." "._QXZ("TSR")." "._QXZ("PAUSE")." "._QXZ("WAIT")." "._QXZ("TALK")." "._QXZ("DISPO")." "._QXZ("STATUS")." "._QXZ("GROUP")." "._QXZ("SUB")."
    \n"; + echo "

    \n\n"; + + echo "\n"; + # JCJ - END CALL LOG SPAN + + + # JCJ - QC LOG span + echo "\n\n
    \n"; + + echo "
    \n"; + + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + + if ($qc_log_id) + { + $checkpoint_stmt="select * from quality_control_checkpoint_log where qc_log_id='$qc_log_id' order by checkpoint_rank asc"; + $checkpoint_rslt=mysql_to_mysqli($checkpoint_stmt, $link); + if (mysqli_num_rows($checkpoint_rslt)==0) + { + echo _QXZ("ERROR - NO QUALITY CONTROL RECORD FOUND!"); + } + else + { + $scorecard_stmt="select qc_scorecard_id, recording_id from quality_control_queue where qc_log_id='$qc_log_id'"; + $scorecard_rslt=mysql_to_mysqli($scorecard_stmt, $link); + $scorecard_row=mysqli_fetch_row($scorecard_rslt); + $qc_scorecard_id=$scorecard_row[0]; + $qc_recording_id=$scorecard_row[1]; + + $stmt="select recording_id,channel,server_ip,extension,start_time,start_epoch,end_time,end_epoch,length_in_sec,length_in_min,filename,location,lead_id,user,vicidial_id from recording_log where recording_id='" . mysqli_real_escape_string($link, $qc_recording_id) . "' order by recording_id desc limit 500;"; + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_row($rslt); + + $location = $row[11]; + + if (strlen($location)>2) + { + $URLserver_ip = $location; + $URLserver_ip = preg_replace('/http:\/\//i', '',$URLserver_ip); + $URLserver_ip = preg_replace('/https:\/\//i', '',$URLserver_ip); + $URLserver_ip = preg_replace('/\/.*/i', '',$URLserver_ip); + $stmt="select count(*) from servers where server_ip='$URLserver_ip';"; + $rsltx=mysql_to_mysqli($stmt, $link); + $rowx=mysqli_fetch_row($rsltx); + + if ($rowx[0] > 0) + { + $stmt="select recording_web_link,alt_server_ip,external_server_ip from servers where server_ip='$URLserver_ip';"; + $rsltx=mysql_to_mysqli($stmt, $link); + $rowx=mysqli_fetch_row($rsltx); + + if (preg_match("/ALT_IP/i",$rowx[0])) + { + $location = preg_replace("/$URLserver_ip/i", "$rowx[1]", $location); + } + if (preg_match("/EXTERNAL_IP/i",$rowx[0])) + { + $location = preg_replace("/$URLserver_ip/i", "$rowx[2]", $location); + } + } + } + + if (strlen($location)>30) + {$locat = substr($location,0,27); $locat = "$locat...";} + else + {$locat = $location;} + $play_audio=''; + if ( (preg_match('/ftp/i',$location)) or (preg_match('/http/i',$location)) ) + { + if ($log_recording_access<1) + { + $play_audio = "     \n"; + $location = "$locat"; + } + else + { + $location = "$locat"; + } + } + else + {$location = $locat;} + + echo "\n"; + echo ""; + echo ""; + echo ""; + echo "\n"; + + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo "\n"; + $i=1; + while ($checkpoint_row=mysqli_fetch_array($checkpoint_rslt)) + { + $qccl_id=$checkpoint_row["qc_checkpoint_log_id"]; + $instant_fail=$checkpoint_row["instant_fail"]; + if (preg_match("/1$|3$|5$|7$|9$/i", $i)) + {$bgcolor="bgcolor='#".$SSstd_row3_background."'";} + else + {$bgcolor="bgcolor='#".$SSstd_row2_background."'";} + + echo ""; + echo ""; + echo ""; + if ($checkpoint_row["instant_fail"]=="Y") + { + echo ""; + } + else + { + echo ""; + } + echo ""; + echo ""; + echo ""; + $i++; + } + echo ""; + echo ""; + echo ""; + echo "\n"; + echo ""; + echo ""; + + # echo ""; + echo ""; + + +# echo ""; + echo ""; + echo "\n"; + echo "
    "._QXZ("SCORECARD ID").": $qc_scorecard_id"._QXZ("RECORDING ID").":
     "._QXZ("Checkpoint").""._QXZ("Fail")."?"._QXZ("Points")."/td>"; + echo ""._QXZ("Comments")."
    $i$checkpoint_row[checkpoint_text]  / $checkpoint_row[checkpoint_points]
    $play_audio  $location
    "._QXZ("FINISH QC").":
    "._QXZ("QC Result").": ("._QXZ("with")." $list_campaign "._QXZ("statuses").")
    \n"; + } + echo "


    "; + } + + + echo ""._QXZ("ALL RECORDINGS FOR THIS LEAD").":\n"; + echo "\n"; + echo "\n"; + + $stmt="select recording_id,channel,server_ip,extension,start_time,start_epoch,end_time,end_epoch,length_in_sec,length_in_min,filename,location,lead_id,user,vicidial_id from recording_log where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "' and recording_id!='" . mysqli_real_escape_string($link, $qc_recording_id) . "' order by recording_id desc limit 500;"; $rslt=mysql_to_mysqli($stmt, $link); $logs_to_print = mysqli_num_rows($rslt); if ($DB) {echo "$logs_to_print|$stmt|\n";} @@ -1371,9 +2218,9 @@ else { $row=mysqli_fetch_row($rslt); if (preg_match("/1$|3$|5$|7$|9$/i", $u)) - {$bgcolor='bgcolor="#B9CBFD"';} + {$bgcolor="bgcolor='#".$SSstd_row2_background."'";} else - {$bgcolor='bgcolor="#9BB9FB"';} + {$bgcolor="bgcolor='#".$SSstd_row1_background."'";} $location = $row[11]; @@ -1408,12 +2255,12 @@ else {$locat = substr($location,0,27); $locat = "$locat...";} else {$locat = $location;} - $play_audio=''; + $play_audio=''; if ( (preg_match('/ftp/i',$location)) or (preg_match('/http/i',$location)) ) { if ($log_recording_access<1) { - $play_audio = "\n"; + $play_audio = "\n"; $location = "$locat"; } else @@ -1425,21 +2272,25 @@ else {$location = $locat;} $u++; echo ""; - echo ""; - echo ""; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo ""; + echo ""; + echo ""; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo ""; echo "$play_audio"; echo "\n"; } echo "
    # "._QXZ("LEAD").""._QXZ("DATE/TIME")." "._QXZ("SECONDS")."   "._QXZ("RECID").""._QXZ("FILENAME").""._QXZ("LOCATION").""._QXZ("TSR")." 
     
    $u $row[12] $row[4] $row[8] $row[0]   $row[10] $location $row[13] $u $row[12] $row[4] $row[8] $row[0]   $row[10] $location $row[13]


    \n"; + echo "
    \n"; + echo "\n"; + echo "\n"; + # END QC LOG SPAN $stmt="SELECT count(*) from vicidial_users where user='$PHP_AUTH_USER' and pass='$PHP_AUTH_PW' and user_level >= 9 and modify_leads IN('1','2','3','4');"; if ($DB) {echo "|$stmt|\n";} @@ -1452,9 +2303,9 @@ else echo ""._QXZ("Click here to see Lead Modify changes to this lead")."\n"; } - echo "\n"; } +echo "\n"; $ENDtime = date("U"); diff --git a/agc_2-X/trunk/www/vicidial/qc_module_actions.php b/agc_2-X/trunk/www/vicidial/qc_module_actions.php new file mode 100644 index 00000000..fcdfbb7c --- /dev/null +++ b/agc_2-X/trunk/www/vicidial/qc_module_actions.php @@ -0,0 +1,674 @@ +|\n|\r|\t|\#.*|;.*/","",$DBCline); + if (ereg("^enckey", $DBCline)) {$enckey = $DBCline; $enckey = preg_replace("/.*=/","",$enckey);} + } +} + + +$PHP_AUTH_USER=$_SERVER['PHP_AUTH_USER']; +$PHP_AUTH_PW=$_SERVER['PHP_AUTH_PW']; +$PHP_SELF=$_SERVER['PHP_SELF']; +$QUERY_STRING = getenv("QUERY_STRING"); + +############################################# +##### START SYSTEM_SETTINGS LOOKUP ##### +$stmt = "SELECT use_non_latin,auto_dial_limit,user_territories_active,allow_custom_dialplan,callcard_enabled,admin_modify_refresh,nocache_admin,webroot_writable,admin_screen_colors,qc_features_active FROM system_settings;"; +$rslt=mysql_to_mysqli($stmt, $link); +if ($DB) {echo "$stmt\n";} +$qm_conf_ct = mysqli_num_rows($rslt); +if ($qm_conf_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $non_latin = $row[0]; + $SSauto_dial_limit = $row[1]; + $SSuser_territories_active = $row[2]; + $SSallow_custom_dialplan = $row[3]; + $SScallcard_enabled = $row[4]; + $SSadmin_modify_refresh = $row[5]; + $SSnocache_admin = $row[6]; + $SSwebroot_writable = $row[7]; + $SSadmin_screen_colors = $row[8]; + $SSqc_features_active = $row[9]; + + # slightly increase limit value, because PHP somehow thinks 2.8 > 2.8 + $SSauto_dial_limit = ($SSauto_dial_limit + 0.001); + } +##### END SETTINGS LOOKUP ##### +########################################### + +if (isset($_GET["DB"])) {$DB=$_GET["DB"];} + elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];} +if (isset($_GET["end_date"])) {$end_date=$_GET["end_date"];} + elseif (isset($_POST["end_date"])) {$end_date=$_POST["end_date"];} +if (isset($_GET["modify_date"])) {$modify_date=$_GET["modify_date"];} + elseif (isset($_POST["modify_date"])) {$modify_date=$_POST["modify_date"];} +if (isset($_GET["claim_rec"])) {$claim_rec=$_GET["claim_rec"];} + elseif (isset($_POST["claim_rec"])) {$claim_rec=$_POST["claim_rec"];} +if (isset($_GET["recording_id"])) {$recording_id=$_GET["recording_id"];} + elseif (isset($_POST["recording_id"])) {$recording_id=$_POST["recording_id"];} +if (isset($_GET["qc_action"])) {$qc_action=$_GET["qc_action"];} + elseif (isset($_POST["qc_action"])) {$qc_action=$_POST["qc_action"];} +if (isset($_GET["mgr_override"])) {$mgr_override=$_GET["mgr_override"];} + elseif (isset($_POST["mgr_override"])) {$mgr_override=$_POST["mgr_override"];} +if (isset($_GET["scorecard_id"])) {$scorecard_id=$_GET["scorecard_id"];} + elseif (isset($_POST["scorecard_id"])) {$scorecard_id=$_POST["scorecard_id"];} +if (isset($_GET["qc_row_id"])) {$qc_row_id=$_GET["qc_row_id"];} + elseif (isset($_POST["qc_row_id"])) {$qc_row_id=$_POST["qc_row_id"];} +if (isset($_GET["qc_log_id"])) {$qc_log_id=$_GET["qc_log_id"];} + elseif (isset($_POST["qc_log_id"])) {$qc_log_id=$_POST["qc_log_id"];} +if (isset($_GET["qc_status"])) {$qc_status=$_GET["qc_status"];} + elseif (isset($_POST["qc_status"])) {$qc_status=$_POST["qc_status"];} +if (isset($_GET["qc_agent_comments"])) {$qc_agent_comments=$_GET["qc_agent_comments"];} + elseif (isset($_POST["qc_agent_comments"])) {$qc_agent_comments=$_POST["qc_agent_comments"];} +if (isset($_GET["qc_manager_comments"])) {$qc_manager_comments=$_GET["qc_manager_comments"];} + elseif (isset($_POST["qc_manager_comments"])) {$qc_manager_comments=$_POST["qc_manager_comments"];} + +if (isset($_GET["field_name"])) {$field_name=$_GET["field_name"];} + elseif (isset($_POST["field_name"])) {$field_name=$_POST["field_name"];} +if (isset($_GET["field_value"])) {$field_value=$_GET["field_value"];} + elseif (isset($_POST["field_value"])) {$field_value=$_POST["field_value"];} + +if (isset($_GET["lead_id"])) {$lead_id=$_GET["lead_id"];} + elseif (isset($_POST["lead_id"])) {$lead_id=$_POST["lead_id"];} +if (isset($_GET["callback_id"])) {$callback_id=$_GET["callback_id"];} + elseif (isset($_POST["callback_id"])) {$callback_id=$_POST["callback_id"];} +if (isset($_GET["recipient"])) {$recipient=$_GET["recipient"];} + elseif (isset($_POST["recipient"])) {$recipient=$_POST["recipient"];} +if (isset($_GET["CBuser"])) {$CBuser=$_GET["CBuser"];} + elseif (isset($_POST["CBuser"])) {$CBuser=$_POST["CBuser"];} +if (isset($_GET["callback_time"])) {$callback_time=$_GET["callback_time"];} + elseif (isset($_POST["callback_time"])) {$callback_time=$_POST["callback_time"];} +if (isset($_GET["callback_comments"])) {$callback_comments=$_GET["callback_comments"];} + elseif (isset($_POST["callback_comments"])) {$callback_comments=$_POST["callback_comments"];} + + +if (isset($_GET["qc_checkpoint_log_id"])) {$qc_checkpoint_log_id=$_GET["qc_checkpoint_log_id"];} + elseif (isset($_POST["qc_checkpoint_log_id"])) {$qc_checkpoint_log_id=$_POST["qc_checkpoint_log_id"];} +if (isset($_GET["qc_level"])) {$qc_level=$_GET["qc_level"];} + elseif (isset($_POST["qc_level"])) {$qc_level=$_POST["qc_level"];} +if (isset($_GET["checkpoint_rank"])) {$checkpoint_rank=$_GET["checkpoint_rank"];} + elseif (isset($_POST["checkpoint_rank"])) {$checkpoint_rank=$_POST["checkpoint_rank"];} +if (isset($_GET["checkpoint_points"])) {$checkpoint_points=$_GET["checkpoint_points"];} + elseif (isset($_POST["checkpoint_points"])) {$checkpoint_points=$_POST["checkpoint_points"];} +if (isset($_GET["checkpoint_points_earned"])) {$checkpoint_points_earned=$_GET["checkpoint_points_earned"];} + elseif (isset($_POST["checkpoint_points_earned"])) {$checkpoint_points_earned=$_POST["checkpoint_points_earned"];} +if (isset($_GET["new_checkpoint_points"])) {$new_checkpoint_points=$_GET["new_checkpoint_points"];} + elseif (isset($_POST["new_checkpoint_points"])) {$new_checkpoint_points=$_POST["new_checkpoint_points"];} +if (isset($_GET["checkpoint_points_failed"])) {$checkpoint_points_failed=$_GET["checkpoint_points_failed"];} + elseif (isset($_POST["checkpoint_points_failed"])) {$checkpoint_points_failed=$_POST["checkpoint_points_failed"];} +if (isset($_GET["old_checkpoint_rank"])) {$old_checkpoint_rank=$_GET["old_checkpoint_rank"];} + elseif (isset($_POST["old_checkpoint_rank"])) {$old_checkpoint_rank=$_POST["old_checkpoint_rank"];} +if (isset($_GET["new_checkpoint_rank"])) {$new_checkpoint_rank=$_GET["new_checkpoint_rank"];} + elseif (isset($_POST["new_checkpoint_rank"])) {$new_checkpoint_rank=$_POST["new_checkpoint_rank"];} +if (isset($_GET["new_active"])) {$new_active=$_GET["new_active"];} + elseif (isset($_POST["new_active"])) {$new_active=$_POST["new_active"];} +if (isset($_GET["new_commission_loss"])) {$new_commission_loss=$_GET["new_commission_loss"];} + elseif (isset($_POST["new_commission_loss"])) {$new_commission_loss=$_POST["new_commission_loss"];} +if (isset($_GET["new_instant_fail"])) {$new_instant_fail=$_GET["new_instant_fail"];} + elseif (isset($_POST["new_instant_fail"])) {$new_instant_fail=$_POST["new_instant_fail"];} +if (isset($_GET["new_admin_notes"])) {$new_admin_notes=$_GET["new_admin_notes"];} + elseif (isset($_POST["new_admin_notes"])) {$new_admin_notes=$_POST["new_admin_notes"];} +if (isset($_GET["new_checkpoint_text"])) {$new_checkpoint_text=$_GET["new_checkpoint_text"];} + elseif (isset($_POST["new_checkpoint_text"])) {$new_checkpoint_text=$_POST["new_checkpoint_text"];} +if (isset($_GET["checkpoint_row_id"])) {$checkpoint_row_id=$_GET["checkpoint_row_id"];} + elseif (isset($_POST["checkpoint_row_id"])) {$checkpoint_row_id=$_POST["checkpoint_row_id"];} +if (isset($_GET["checkpoint_comment_agent"])) {$checkpoint_comment_agent=$_GET["checkpoint_comment_agent"];} + elseif (isset($_POST["checkpoint_comment_agent"])) {$checkpoint_comment_agent=$_POST["checkpoint_comment_agent"];} +if (isset($_GET["checkpoint_answer"])) {$checkpoint_answer=$_GET["checkpoint_answer"];} + elseif (isset($_POST["checkpoint_answer"])) {$checkpoint_answer=$_POST["checkpoint_answer"];} +if (isset($_GET["instant_fail"])) {$instant_fail=$_GET["instant_fail"];} + elseif (isset($_POST["instant_fail"])) {$instant_fail=$_POST["instant_fail"];} +if (isset($_GET["admin_notes"])) {$admin_notes=$_GET["admin_notes"];} + elseif (isset($_POST["admin_notes"])) {$admin_notes=$_POST["admin_notes"];} +if (isset($_GET["commission_loss"])) {$commission_loss=$_GET["commission_loss"];} + elseif (isset($_POST["commission_loss"])) {$commission_loss=$_POST["commission_loss"];} +if (isset($_GET["parameter"])) {$parameter=$_GET["parameter"];} + elseif (isset($_POST["parameter"])) {$parameter=$_POST["parameter"];} +if (isset($_GET["parameter_value"])) {$parameter_value=$_GET["parameter_value"];} + elseif (isset($_POST["parameter_value"])) {$parameter_value=$_POST["parameter_value"];} +if (isset($_GET["recording_timestamp"])) {$recording_timestamp=$_GET["recording_timestamp"];} + elseif (isset($_POST["recording_timestamp"])) {$recording_timestamp=$_POST["recording_timestamp"];} +if (isset($_POST["upd_customer"])) {$upd_customer=$_POST["upd_customer"];} + elseif (isset($_GET["upd_customer"])) {$upd_customer=$_GET["upd_customer"];} +if (isset($_POST["view_epoch"])) {$view_epoch=$_POST["view_epoch"];} + elseif (isset($_GET["view_epoch"])) {$view_epoch=$_GET["view_epoch"];} + +$defaultappointment = date("Y-m-d"); +$NOW_TIME = date("Y-m-d H:i:s"); +$STARTtime = date("U"); + +$rights_stmt = "SELECT modify_leads,qc_enabled,full_name,modify_leads,user_group,selected_language from vicidial_users where user='$PHP_AUTH_USER';"; +if ($DB) {echo "|$stmt|\n";} +$rights_rslt=mysql_to_mysqli($rights_stmt, $link); +$rights_row=mysqli_fetch_row($rights_rslt); +$modify_leads = $rights_row[0]; +$qc_enabled = $rights_row[1]; +$LOGfullname = $rights_row[2]; +$LOGmodify_leads = $rights_row[3]; +$LOGuser_group = $rights_row[4]; +$VUselected_language = $rights_row[5]; + +if ($qc_log_id) + { + $queue_stmt="select * from quality_control_queue where qc_log_id='$qc_log_id'"; + $queue_rslt=mysql_to_mysqli($queue_stmt, $link); + $queue_row=mysqli_fetch_array($queue_rslt); + $queue_user=$queue_row["user"]; + $queue_user_group=$queue_row["user_group"]; + $queue_list_id=$queue_row["list_id"]; + $queue_campaign_id=$queue_row["campaign_id"]; + $queue_lead_id=$queue_row["lead_id"]; + $queue_qc_user_group=$queue_row["qc_user_group"]; + } + +$auth=0; +$auth_message = user_authorization($PHP_AUTH_USER,$PHP_AUTH_PW,'QC',1,0); +if ($auth_message == 'GOOD') + {$auth=1;} + +if ($auth < 1) + { + $VDdisplayMESSAGE = _QXZ("Login incorrect, please try again"); + if ($auth_message == 'LOCK') + { + $VDdisplayMESSAGE = _QXZ("Too many login attempts, try again in 15 minutes"); + Header ("Content-type: text/html; charset=utf-8"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; + exit; + } + if ($auth_message == 'IPBLOCK') + { + $VDdisplayMESSAGE = _QXZ("Your IP Address is not allowed") . ": $ip"; + Header ("Content-type: text/html; charset=utf-8"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; + exit; + } + Header("WWW-Authenticate: Basic realm=\"CONTACT-CENTER-ADMIN\""); + Header("HTTP/1.0 401 Unauthorized"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$PHP_AUTH_PW|$auth_message|\n"; + exit; + } + +if ( $qc_enabled < 1 ) + { + header ("Content-type: text/html; charset=utf-8"); + echo _QXZ("QC is not enabled for your user account")."\n"; + exit; + } + + +$SSmenu_background='015B91'; +$SSframe_background='D9E6FE'; +$SSstd_row1_background='9BB9FB'; +$SSstd_row2_background='B9CBFD'; +$SSstd_row3_background='8EBCFD'; +$SSstd_row4_background='B6D3FC'; +$SSstd_row5_background='A3C3D6'; +$SSalt_row1_background='BDFFBD'; +$SSalt_row2_background='99FF99'; +$SSalt_row3_background='CCFFCC'; + +if ($SSadmin_screen_colors != 'default') + { + $stmt = "SELECT menu_background,frame_background,std_row1_background,std_row2_background,std_row3_background,std_row4_background,std_row5_background,alt_row1_background,alt_row2_background,alt_row3_background,web_logo FROM vicidial_screen_colors where colors_id='$SSadmin_screen_colors';"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {echo "$stmt\n";} + $colors_ct = mysqli_num_rows($rslt); + if ($colors_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $SSmenu_background = $row[0]; + $SSframe_background = $row[1]; + $SSstd_row1_background = $row[2]; + $SSstd_row2_background = $row[3]; + $SSstd_row3_background = $row[4]; + $SSstd_row4_background = $row[5]; + $SSstd_row5_background = $row[6]; + $SSalt_row1_background = $row[7]; + $SSalt_row2_background = $row[8]; + $SSalt_row3_background = $row[9]; + $SSweb_logo = $row[10]; + } + } +$Mhead_color = $SSstd_row5_background; +$Mmain_bgcolor = $SSmenu_background; +$Mhead_color = $SSstd_row5_background; + +$NWB = "\"HELP\""; + +if ($qc_checkpoint_log_id && $qc_action=="upd_customer") { + $upd_stmt="update quality_control_checkpoint_log set checkpoint_comment_agent='".mysqli_escape_string($link, $checkpoint_comment_agent)."', instant_fail='".mysqli_escape_string($link, $instant_fail)."', checkpoint_points_earned='".mysqli_escape_string($link, $checkpoint_points_earned)."' where qc_checkpoint_log_id='$qc_checkpoint_log_id'"; + $upd_rslt=mysqli_query($link, $upd_stmt); + #echo mysqli_affected_rows($link); + if ($DB) {echo "|$upd_stmt|\n";} + if (mysqli_affected_rows($link)>0) + { + # Check if there's not already a log record for this visit... + $stmt="select count(*) From vicidial_qc_agent_log where lead_id='$queue_lead_id' and view_epoch='$view_epoch' and details='Scorecard modified'"; + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_row($rslt); + + if ($row[0]==0) + { + $elapsed_seconds=$STARTtime-$view_epoch; + $stmt="INSERT INTO vicidial_qc_agent_log (qc_user,qc_user_group,qc_user_ip,lead_user,web_server_ip,view_datetime,view_epoch,save_epoch,elapsed_seconds,lead_id,list_id,campaign_id,processed,details) values('" . mysqli_real_escape_string($link, $PHP_AUTH_USER) . "','$LOGuser_group','".$_SERVER['REMOTE_ADDR']."','$lead_user','".$_SERVER['SERVER_ADDR']."','$NOW_TIME','$view_epoch','$STARTtime','$elapsed_seconds','" . mysqli_real_escape_string($link, $queue_lead_id) . "','" . mysqli_real_escape_string($link, $queue_list_id) . "','" . mysqli_real_escape_string($link, $queue_campaign_id) . "','N','Scorecard modified')"; + $rslt=mysql_to_mysqli($stmt, $link); + } + } +} + + +if ($qc_action=="check_lead_status" && $modify_date && $lead_id) + { + $stmt="select * From vicidial_list where lead_id='$lead_id' and modify_date>'$modify_date' limit 1"; + $rslt=mysql_to_mysqli($stmt, $link); + $rslt_str=mysqli_num_rows($rslt)."\n"; + while ($row=mysqli_fetch_array($rslt)) + { + $rslt_str.="$row[modify_date]|"; + $rslt_str.="$row[status]|"; + $rslt_str.="$row[vendor_lead_code]|"; + $rslt_str.="$row[user]|"; + $rslt_str.="$row[called_count]|"; + $rslt_str.="$row[title]|"; + $rslt_str.="$row[first_name]|"; + $rslt_str.="$row[middle_initial]|"; + $rslt_str.="$row[last_name]|"; + $rslt_str.="$row[address1]|"; + $rslt_str.="$row[address2]|"; + $rslt_str.="$row[address3]|"; + $rslt_str.="$row[city]|"; + $rslt_str.="$row[state]|"; + $rslt_str.="$row[postal_code]|"; + $rslt_str.="$row[province]|"; + $rslt_str.="$row[country_code]|"; + $rslt_str.="$row[phone_number]|"; + $rslt_str.="$row[phone_code]|"; + $rslt_str.="$row[alt_phone]|"; + $rslt_str.="$row[email]|"; + $rslt_str.="$row[security_phrase]|"; + $rslt_str.="$row[rank]|"; + $rslt_str.="$row[owner]|"; + $rslt_str.="$row[comments]|"; + } + echo $rslt_str; + } + +/* +if ($qc_action=="log_responses" && $qc_checkpoint_log_id && ($checkpoint_answer || $recording_timestamp)) { + $recording_timestamp=preg_replace("/[^0-9\:]/", "", $recording_timestamp); + $upd_stmt="update quality_control_checkpoint_log set checkpoint_answer='$checkpoint_answer', recording_timestamp='".mysqli_escape_string($link, $recording_timestamp)."' where qc_checkpoint_log_id='$qc_checkpoint_log_id' limit 1"; + if ($DB) {echo "|$upd_stmt|\n";} + $upd_rslt=mysqli_query($link, $upd_stmt); + echo mysqli_affected_rows($link); + if ($instant_fail=="Y" && $checkpoint_answer=="N") { + # $allq_stmt="select distinct qc_row_id from quality_control_checkpoint_log where qc_checkpoint_log_id='$qc_checkpoint_log_id'"; + # $allq_rslt=mysqli_query($link, $allq_stmt); + # while ($allq_row=mysqli_fetch_row($allq_rslt)) { + # $qc_row_id=$allq_row[0]; + # $upd_stmt="update quality_control_checkpoint_log set checkpoint_points_failed=checkpoint_points_max where qc_row_id='$qc_row_id'"; + # $upd_rslt=mysqli_query($link, $upd_stmt); + # } + } +} +*/ + +if ($qc_action=="update_vl_field" && $lead_id && $field_name) + { + $old_data_stmt="select $field_name from vicidial_list where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "'"; + $old_data_rslt=mysql_to_mysqli($old_data_stmt, $link); + $od_row=mysqli_fetch_row($old_data_rslt); + $old_value=$od_row[0]; + + $stmt="UPDATE vicidial_list set $field_name='" . mysqli_real_escape_string($link, $field_value) . "' where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "' limit 1"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + if (mysqli_affected_rows($link)>0) + { + $details="----$field_name----\n" . mysqli_real_escape_string($link, $old_value) . " => " . mysqli_real_escape_string($link, $field_value) . "\n"; + $elapsed_seconds=$STARTtime-$view_epoch; + + $upd_stmt="UPDATE vicidial_qc_agent_log set details=if(details is null, '$details', CONCAT(details, '$details')), save_datetime='$NOW_TIME', save_epoch='$STARTtime', elapsed_seconds='$elapsed_seconds' where view_epoch='$view_epoch' and lead_id='$lead_id' and qc_log_id='$qc_log_id'"; + echo $upd_stmt."\n"; + $upd_rslt=mysql_to_mysqli($upd_stmt, $link); + } + } + +if ($qc_action=="update_callback") + { + # $DB=1; + if ($callback_id && ($recipient || $CBuser || $callback_time)) + { + $update_cb_SQL=""; + if ($recipient) {$update_cb_SQL.="recipient='$recipient', ";} + if ($CBuser) {$update_cb_SQL.="user='$CBuser', ";} + if ($callback_time) {$update_cb_SQL.="callback_time='$callback_time', ";} + if ($callback_comments) {$update_cb_SQL.="comments='" . mysqli_real_escape_string($link, $callback_comments) . "', ";} + $update_cb_SQL=preg_replace('/, $/', "", $update_cb_SQL); + if (strlen($update_cb_SQL)==0) {echo "0"; exit;} + + $update_cb_stmt="UPDATE vicidial_callbacks set $update_cb_SQL where callback_id='" . mysqli_real_escape_string($link, $callback_id) . "'"; + if ($DB) {echo "|$update_cb_stmt|\n";} + $update_cb_rslt=mysql_to_mysqli($update_cb_stmt, $link); + echo mysqli_affected_rows($link); + if (mysqli_affected_rows($link)>0) + { + $elapsed_seconds=$STARTtime-$view_epoch; + $details=preg_replace('/[\"\']/', "", $update_cb_SQL); + $details=preg_replace('/,\s?/', "\n", $details); + + $stmt="INSERT INTO vicidial_qc_agent_log (qc_user,qc_user_group,qc_user_ip,lead_user,web_server_ip,view_datetime,view_epoch,save_datetime,save_epoch,elapsed_seconds,lead_id,list_id,campaign_id,processed,details) + values('" . mysqli_real_escape_string($link, $PHP_AUTH_USER) . "','$LOGuser_group','".$_SERVER['REMOTE_ADDR']."','$queue_user','".$_SERVER['SERVER_ADDR']."','$NOW_TIME','$view_epoch','$NOW_TIME','$STARTtime','$elapsed_seconds','" . mysqli_real_escape_string($link, $queue_lead_id) . "','" . mysqli_real_escape_string($link, $queue_list_id) . "','" . mysqli_real_escape_string($link, $queue_campaign_id) . "','N','---updated callback---\n" . mysqli_real_escape_string($link, $details) . "')"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + + # QC_log(); + } + } + else + { + echo "0"; + } + } +if ($qc_action=="update_lead_information" && $lead_id) + { + $stmt="UPDATE vicidial_list set status='" . mysqli_real_escape_string($link, $status) . "',title='" . mysqli_real_escape_string($link, $title) . "',first_name='" . mysqli_real_escape_string($link, $first_name) . "',middle_initial='" . mysqli_real_escape_string($link, $middle_initial) . "',last_name='" . mysqli_real_escape_string($link, $last_name) . "',address1='" . mysqli_real_escape_string($link, $address1) . "',address2='" . mysqli_real_escape_string($link, $address2) . "',address3='" . mysqli_real_escape_string($link, $address3) . "',city='" . mysqli_real_escape_string($link, $city) . "',state='" . mysqli_real_escape_string($link, $state) . "',province='" . mysqli_real_escape_string($link, $province) . "',postal_code='" . mysqli_real_escape_string($link, $postal_code) . "',country_code='" . mysqli_real_escape_string($link, $country_code) . "',alt_phone='" . mysqli_real_escape_string($link, $alt_phone) . "',phone_number='$phone_number',phone_code='$phone_code',email='" . mysqli_real_escape_string($link, $email) . "',security_phrase='" . mysqli_real_escape_string($link, $security) . "',comments='" . mysqli_real_escape_string($link, $comments) . "',rank='" . mysqli_real_escape_string($link, $rank) . "',owner='" . mysqli_real_escape_string($link, $owner) . "' where lead_id='" . mysqli_real_escape_string($link, $lead_id) . "'"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + } + +if ($qc_action=="save_comments" && $qc_checkpoint_log_id && $checkpoint_comment_agent && $qc_level) { + if ($qc_level=="agent") { + $column="checkpoint_comment_agent"; + } else { + $column="checkpoint_comment_manager"; + } + $upd_stmt="update quality_control_checkpoint_log set $column='$checkpoint_comment_agent' where qc_checkpoint_log_id='$qc_checkpoint_log_id' limit 1"; + if ($DB) {echo "|$upd_stmt|\n";} + $upd_rslt=mysqli_query($link, $upd_stmt); + echo mysqli_affected_rows($link); +} + +if ($scorecard_id && $qc_action=="add_checkpoint" && $new_checkpoint_rank && $new_checkpoint_text && $new_active) { + $upd_stmt="update quality_control_checkpoints set checkpoint_rank=checkpoint_rank+1, modify_user='$PHP_AUTH_USER' where qc_scorecard_id='$scorecard_id' and checkpoint_rank>=$new_checkpoint_rank"; + $upd_rslt=mysqli_query($link, $upd_stmt); + + $ins_stmt="insert into quality_control_checkpoints(qc_scorecard_id, checkpoint_rank, checkpoint_text, checkpoint_points, active, instant_fail, admin_notes, create_date, create_user) VALUES('".mysqli_real_escape_string($link, $scorecard_id)."', '".mysqli_real_escape_string($link, $new_checkpoint_rank)."', '".mysqli_real_escape_string($link, $new_checkpoint_text)."', '".mysqli_real_escape_string($link, $new_checkpoint_points)."', '".mysqli_real_escape_string($link, $new_active)."', '".mysqli_real_escape_string($link, $new_instant_fail)."', '".mysqli_real_escape_string($link, $new_admin_notes)."', now(), '".mysqli_real_escape_string($link, $PHP_AUTH_USER)."')"; + echo $ins_stmt; + $ins_rslt=mysqli_query($link, $ins_stmt); + + if (mysqli_affected_rows($link)>0) { + $upd_stmt2="update quality_control_scorecards set last_modified=now() where qc_scorecard_id='$scorecard_id'"; + $upd_rslt2=mysqli_query($link, $upd_stmt2); + } +} +if ($scorecard_id && $qc_action=="update_scorecard" && $parameter) + { + $upd_stmt="update quality_control_scorecards set $parameter='".mysqli_real_escape_string($link, $parameter_value)."' where qc_scorecard_id='$scorecard_id'"; + $upd_rslt=mysqli_query($link, $upd_stmt); + if (mysqli_affected_rows($link)>0) + { + $upd_stmt2="update quality_control_scorecards set last_modified=now() where qc_scorecard_id='$scorecard_id'"; + $upd_rslt2=mysqli_query($link, $upd_stmt2); + } + } +if ($scorecard_id && $qc_action=="update_checkpoint" && $checkpoint_row_id && $parameter) { + + if ($parameter && $parameter_value && $parameter!="checkpoint_rank") { + $upd_stmt="update quality_control_checkpoints set $parameter='".mysqli_real_escape_string($link, $parameter_value)."', modify_user='$PHP_AUTH_USER' where qc_scorecard_id='$scorecard_id' and checkpoint_row_id='$checkpoint_row_id'"; + $upd_rslt=mysqli_query($link, $upd_stmt); + if (mysqli_affected_rows($link)>0) { + $upd_stmt2="update quality_control_scorecards set last_modified=now() where qc_scorecard_id='$scorecard_id'"; + $upd_rslt2=mysqli_query($link, $upd_stmt2); + } + } else if ($parameter=="checkpoint_rank" && $new_checkpoint_rank && $old_checkpoint_rank) { + $upd_stmt="update quality_control_checkpoints set checkpoint_rank='$new_checkpoint_rank', modify_user='$PHP_AUTH_USER' where qc_scorecard_id='$scorecard_id' and checkpoint_row_id='$checkpoint_row_id'"; + $upd_rslt=mysqli_query($link, $upd_stmt); + if (mysqli_affected_rows($link)>0) { + $upd_stmt2="update quality_control_scorecards set last_modified=now() where qc_scorecard_id='$scorecard_id'"; + $upd_rslt2=mysqli_query($link, $upd_stmt2); + + if ($new_checkpoint_rank>$old_checkpoint_rank) { + $upd_stmt2="update quality_control_checkpoints set checkpoint_rank=checkpoint_rank-1, modify_user='$PHP_AUTH_USER' where qc_scorecard_id='$scorecard_id' and checkpoint_rank>$old_checkpoint_rank and checkpoint_rank<=$new_checkpoint_rank and checkpoint_row_id!='$checkpoint_row_id'"; + } else { + $upd_stmt2="update quality_control_checkpoints set checkpoint_rank=checkpoint_rank+1, modify_user='$PHP_AUTH_USER' where qc_scorecard_id='$scorecard_id' and checkpoint_rank>=$new_checkpoint_rank and checkpoint_rank<$old_checkpoint_rank and checkpoint_row_id!='$checkpoint_row_id'"; + } + $upd_rslt2=mysqli_query($link, $upd_stmt2); + } + } +} +if ($scorecard_id && $qc_action=="delete_checkpoint" && $checkpoint_rank && $checkpoint_row_id) { + $delete_stmt="delete from quality_control_checkpoints where qc_scorecard_id='$scorecard_id' and checkpoint_row_id='$checkpoint_row_id'"; + $delete_rslt=mysqli_query($link, $delete_stmt); + if (mysqli_affected_rows($link)>0) { + $upd_stmt="update quality_control_checkpoints set checkpoint_rank=checkpoint_rank-1, modify_user='$PHP_AUTH_USER' where qc_scorecard_id='$scorecard_id' and checkpoint_rank>$checkpoint_rank"; + $upd_rslt=mysqli_query($link, $upd_stmt); + + $upd_stmt2="update quality_control_scorecards set last_modified=now() where qc_scorecard_id='$scorecard_id'"; + $upd_rslt2=mysqli_query($link, $upd_stmt2); + } +} + +if ($qc_action=="new_scorecard") + { + echo "
    \n"; + echo "\n"; + echo "\t\n"; + echo "\t\n"; + echo "\n"; + echo "\n"; + echo "\t\n"; + echo "\t\n"; + echo "\n"; + echo "\n"; + echo "\t\n"; + echo "\t\n"; + echo "\n"; + echo "\n"; + echo "\t\n"; + echo "\t\n"; + echo "\n"; + echo "\t\n"; + echo "\t\n"; + echo "\n"; + echo "
    "._QXZ("ADD NEW SCORECARD")."
    "._QXZ("Scorecard ID").":$NWB#qc_scorecards-new_scorecard_id$NWE
    "._QXZ("Scorecard name").":$NWB#qc_scorecards-new_scorecard_name$NWE
    "._QXZ("Active").":$NWB#qc_scorecards-new_active$NWE
    \n"; + echo "
    \n"; + } + +if ($scorecard_id && $qc_action=="load_checkpoints") { + $new_qstmt="select if(max(checkpoint_rank) is not null, max(checkpoint_rank)+1, 1) from quality_control_checkpoints where qc_scorecard_id='$scorecard_id'"; + $new_qrslt=mysqli_query($link, $new_qstmt); + $qrow=mysqli_fetch_row($new_qrslt); + $next_rank=$qrow[0]; + + $stmt="select * from quality_control_scorecards where qc_scorecard_id='$scorecard_id'"; + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_array($rslt); + $scorecard_name=$row["scorecard_name"]; + $passing_score=$row["passing_score"]; + + echo "\n"; + $stmt="select * from quality_control_checkpoints where qc_scorecard_id='$scorecard_id' order by checkpoint_rank"; + $rslt=mysqli_query($link, $stmt); + if (mysqli_num_rows($rslt)>0) { + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + $i++; + if ($i%2==0) {$bgcolor=$SSstd_row1_background;} else {$bgcolor=$SSstd_row2_background;} + echo "\n"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + # echo ""; + echo ""; + echo ""; + $max_score=0; + while ($row=mysqli_fetch_array($rslt)) { + echo ""; + echo ""; + echo ""; + echo "\n"; + echo "\n"; + echo ""; + echo "\n"; + # echo ""; + echo ""; + echo ""; + } + echo ""; + } else { + echo "\n"; + echo ""; + echo ""; + echo ""; + } + + echo "\n"; + + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + #echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo "\n"; + echo ""; + echo ""; + echo "\n"; +# echo ""; + echo ""; + echo ""; + echo "
    "._QXZ("MODIFY QC SCORECARD")." $scorecard_id $NWB#qc_scorecards-modify$NWE
    "._QXZ("NAME").":
    "._QXZ("Order")."$NWB#qc_scorecards-order$NWE"._QXZ("Active")."$NWB#qc_scorecards-active_checkpoint$NWE"._QXZ("Checkpoint Text")."$NWB#qc_scorecards-checkpoint_text$NWE"._QXZ("Points")."$NWB#qc_scorecards-points$NWE"._QXZ("Instant Fail")."$NWB#qc_scorecards-instant_kill$NWE"._QXZ("Admin Notes")."$NWB#qc_scorecards-admin_notes$NWECommission Loss 
    \n"; + echo "\n"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + # echo ""; + # echo "
    "._QXZ("PASSING SCORE").":/ $max_score 
    ** "._QXZ("CURRENTLY NO CHECKPOINTS FOR SCORECARD")." $scorecard_id **
    "._QXZ("NAME").":
     
    "._QXZ("ADD NEW CHECKPOINT FOR SCORECARD")." $scorecard_id
    "._QXZ("Order")."$NWB#qc_scorecards-order$NWE"._QXZ("Active")."$NWB#qc_scorecards-active_checkpoint$NWE"._QXZ("Checkpoint Text")."$NWB#qc_scorecards-checkpoint_text$NWE"._QXZ("Points")."$NWB#qc_scorecards-points$NWE"._QXZ("Instant Kill")."$NWB#qc_scorecards-instant_kill$NWE"._QXZ("Admin Notes")."$NWB#qc_scorecards-admin_notes$NWECommission loss 
    "; + echo "\n"; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; +# echo ""; +# echo "
    \n"; +} + +if ($qc_action=="reload_scorecard_display") + { + echo "\n"; + echo "\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\n"; + # \n"; + echo "\t\t\t\n"; + + $qstmt="select count(*), sum(checkpoint_points) from quality_control_checkpoints where qc_scorecard_id='$row[qc_scorecard_id]'"; + $qrslt=mysql_to_mysqli($qstmt, $link); + $qrow=mysqli_fetch_row($qrslt); + $checkpoints=$qrow[0]; + ($checkpoints==0 ? $score_total="--" : $score_total=$qrow[1]); + echo "\t\t\t\n"; + echo "\t\t\t\n"; + + + $qstmt="select count(*) from vicidial_campaigns where qc_scorecard_id='$row[qc_scorecard_id]'"; + $qrslt=mysql_to_mysqli($qstmt, $link); + $qrow=mysqli_fetch_row($qrslt); + $campaigns_in_use=$qrow[0]; + echo "\t\t\t\n"; + + + $qstmt="select count(*) from vicidial_inbound_groups where qc_scorecard_id='$row[qc_scorecard_id]'"; + $qrslt=mysql_to_mysqli($qstmt, $link); + $qrow=mysqli_fetch_row($qrslt); + $ingroups_in_use=$qrow[0]; + echo "\t\t\t\n"; + + + $qstmt="select count(*) from vicidial_lists where qc_scorecard_id='$row[qc_scorecard_id]'"; + $qrslt=mysql_to_mysqli($qstmt, $link); + $qrow=mysqli_fetch_row($qrslt); + $lists_in_use=$qrow[0]; + echo "\t\t\t\n"; + echo "\t\t\t\n"; + echo "\t\t\t\n"; + + echo "\t\t\t\n"; + echo "\t\t\t\n"; + echo ""; + } + echo "\t\n"; + echo "\t\t\n"; + echo "
    "._QXZ("Scorecard").""._QXZ("Checkpoints").""._QXZ("Pass/max score").""._QXZ("Campaigns").""._QXZ("In-groups").""._QXZ("Lists").""._QXZ("Last modified").""._QXZ("Active")."  
    $row[qc_scorecard_id] - $row[scorecard_name]$checkpoints$row[passing_score] / $score_total$campaigns_in_use$ingroups_in_use$lists_in_use$row[last_modified]
    \n"; + echo "\t
    \n"; + } + +# QC_log($PHP_AUTH_USER, $queue_qc_user_group, $_SERVER['REMOTE_ADDR'], $queue_user, $_SERVER['SERVER_ADDR'], $queue_lead_id, $queue_list_id, $queue_campaign_id, $details); +function QC_log($qc_user, $queue_user, $queue_lead_id, $queue_list_id, $details) + { + global $link, $qc_row_id, $NOW_TIME, $view_epoch; + + $stmt="INSERT INTO vicidial_qc_agent_log (qc_user,qc_user_group,qc_user_ip,lead_user,web_server_ip,view_datetime,view_epoch,lead_id,list_id,campaign_id,processed,details) values('" . mysqli_real_escape_string($link, $PHP_AUTH_USER) . "','$LOGuser_group','".$_SERVER['REMOTE_ADDR']."','$lead_user','".$_SERVER['SERVER_ADDR']."','$NOW_TIME','$view_epoch','" . mysqli_real_escape_string($link, $queue_lead_id) . "','" . mysqli_real_escape_string($link, $queue_list_id) . "','" . mysqli_real_escape_string($link, $queue_campaign_id) . "','N','$details')"; + $rslt=mysql_to_mysqli($stmt, $link); + + } \ No newline at end of file diff --git a/agc_2-X/trunk/www/vicidial/qc_scorecards.php b/agc_2-X/trunk/www/vicidial/qc_scorecards.php new file mode 100644 index 00000000..9b9eba5c --- /dev/null +++ b/agc_2-X/trunk/www/vicidial/qc_scorecards.php @@ -0,0 +1,768 @@ + LICENSE: AGPLv2 +# +# this screen manages QC Scorecards within VICIdial +# +# changes: +# 210306-1532 - First Build +# + +$admin_version = '2.14-1'; +$build = '210306-1532'; + +header ("Content-type: text/html; charset=utf-8"); + +require("dbconnect_mysqli.php"); # /srv/www/vhosts/vicimarketing/vicidial/ +require("functions.php"); +$link=mysqli_connect("$VARDB_server", "$VARDB_user", "$VARDB_pass", "$VARDB_database", $VARDB_port); +if (!$link) + { + die("MySQL connect ERROR: " . mysqli_error('mysqli')); + } + +$PHP_AUTH_USER=$_SERVER['PHP_AUTH_USER']; +$PHP_AUTH_PW=$_SERVER['PHP_AUTH_PW']; +$PHP_SELF=$_SERVER['PHP_SELF']; +$QUERY_STRING = getenv("QUERY_STRING"); + +############################################# +##### START SYSTEM_SETTINGS LOOKUP ##### +$stmt = "SELECT use_non_latin,auto_dial_limit,user_territories_active,allow_custom_dialplan,callcard_enabled,admin_modify_refresh,nocache_admin,webroot_writable,admin_screen_colors,qc_features_active,hosted_settings FROM system_settings;"; +$rslt=mysql_to_mysqli($stmt, $link); +if ($DB) {echo "$stmt\n";} +$qm_conf_ct = mysqli_num_rows($rslt); +if ($qm_conf_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $non_latin = $row[0]; + $SSauto_dial_limit = $row[1]; + $SSuser_territories_active = $row[2]; + $SSallow_custom_dialplan = $row[3]; + $SScallcard_enabled = $row[4]; + $SSadmin_modify_refresh = $row[5]; + $SSnocache_admin = $row[6]; + $SSwebroot_writable = $row[7]; + $SSadmin_screen_colors = $row[8]; + $SSqc_features_active = $row[9]; + $SShosted_settings = $row[10]; + + # slightly increase limit value, because PHP somehow thinks 2.8 > 2.8 + $SSauto_dial_limit = ($SSauto_dial_limit + 0.001); + } +##### END SETTINGS LOOKUP ##### +########################################### + +$PHP_AUTH_USER = preg_replace('/[^-_0-9\p{L}]/u','',$PHP_AUTH_USER); + +if ( file_exists("/etc/mysql_enc.conf") ) { + $DBCagc = file("/etc/mysql_enc.conf"); + foreach ($DBCagc as $DBCline) { + $DBCline = preg_replace("/ |>|\n|\r|\t|\#.*|;.*/","",$DBCline); + if (ereg("^enckey", $DBCline)) {$enckey = $DBCline; $enckey = preg_replace("/.*=/","",$enckey);} + } +} + +if (isset($_GET["DB"])) {$DB=$_GET["DB"];} + elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];} +if (isset($_GET["submit"])) {$submit=$_GET["submit"];} + elseif (isset($_POST["submit"])) {$submit=$_POST["submit"];} +if (isset($_GET["new_scorecard_id"])) {$new_scorecard_id=$_GET["new_scorecard_id"];} + elseif (isset($_POST["new_scorecard_id"])) {$new_scorecard_id=$_POST["new_scorecard_id"];} +if (isset($_GET["new_scorecard_name"])) {$new_scorecard_name=$_GET["new_scorecard_name"];} + elseif (isset($_POST["new_scorecard_name"])) {$new_scorecard_name=$_POST["new_scorecard_name"];} +if (isset($_GET["new_active"])) {$new_active=$_GET["new_active"];} + elseif (isset($_POST["new_active"])) {$new_active=$_POST["new_active"];} +if (isset($_GET["active"])) {$active=$_GET["active"];} + elseif (isset($_POST["active"])) {$active=$_POST["active"];} +if (isset($_GET["action"])) {$action=$_GET["action"];} + elseif (isset($_POST["action"])) {$action=$_POST["action"];} +if (isset($_GET["confirm_deletion"])) {$confirm_deletion=$_GET["confirm_deletion"];} + elseif (isset($_POST["confirm_deletion"])) {$confirm_deletion=$_POST["confirm_deletion"];} +if (isset($_GET["scorecard_id"])) {$scorecard_id=$_GET["scorecard_id"];} + elseif (isset($_POST["scorecard_id"])) {$scorecard_id=$_POST["scorecard_id"];} + +$new_scorecard_id = preg_replace('/[^-_0-9a-zA-Z]/','',$new_scorecard_id); +$new_scorecard_name = preg_replace('/[^- \.\,\_0-9a-zA-Z]/','',$new_scorecard_name); +$new_active = preg_replace('/[^NY]/','',$new_active); +$active = preg_replace('/[^NY]/','',$active); + + +$SSmenu_background='015B91'; +$SSframe_background='D9E6FE'; +$SSstd_row1_background='9BB9FB'; +$SSstd_row2_background='B9CBFD'; +$SSstd_row3_background='8EBCFD'; +$SSstd_row4_background='B6D3FC'; +$SSstd_row5_background='A3C3D6'; +$SSalt_row1_background='BDFFBD'; +$SSalt_row2_background='99FF99'; +$SSalt_row3_background='CCFFCC'; + +if ($SSadmin_screen_colors != 'default') + { + $stmt = "SELECT menu_background,frame_background,std_row1_background,std_row2_background,std_row3_background,std_row4_background,std_row5_background,alt_row1_background,alt_row2_background,alt_row3_background,web_logo FROM vicidial_screen_colors where colors_id='$SSadmin_screen_colors';"; + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {echo "$stmt\n";} + $colors_ct = mysqli_num_rows($rslt); + if ($colors_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $SSmenu_background = $row[0]; + $SSframe_background = $row[1]; + $SSstd_row1_background = $row[2]; + $SSstd_row2_background = $row[3]; + $SSstd_row3_background = $row[4]; + $SSstd_row4_background = $row[5]; + $SSstd_row5_background = $row[6]; + $SSalt_row1_background = $row[7]; + $SSalt_row2_background = $row[8]; + $SSalt_row3_background = $row[9]; + $SSweb_logo = $row[10]; + } + } +$Mhead_color = $SSstd_row5_background; +$Mmain_bgcolor = $SSmenu_background; +$Mhead_color = $SSstd_row5_background; + +if ($submit==_QXZ("SUBMIT NEW SCORECARD")) { + $ins_stmt="insert into quality_control_scorecards(qc_scorecard_id, scorecard_name, active) VALUES('".mysqli_escape_string($link, $new_scorecard_id)."', '".mysqli_escape_string($link, $new_scorecard_name)."', '$new_active')"; + $ins_rslt=mysql_to_mysqli($ins_stmt, $link); +} + +# Valid user +$auth=0; +$auth_message = user_authorization($PHP_AUTH_USER,$PHP_AUTH_PW,'',1,0); +if ($auth_message == 'GOOD') + {$auth=1;} + +if ($auth < 1) + { + $VDdisplayMESSAGE = _QXZ("Login incorrect, please try again"); + if ($auth_message == 'LOCK') + { + $VDdisplayMESSAGE = _QXZ("Too many login attempts, try again in 15 minutes"); + Header ("Content-type: text/html; charset=utf-8"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; + exit; + } + if ($auth_message == 'IPBLOCK') + { + $VDdisplayMESSAGE = _QXZ("Your IP Address is not allowed") . ": $ip"; + Header ("Content-type: text/html; charset=utf-8"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; + exit; + } + Header("WWW-Authenticate: Basic realm=\"CONTACT-CENTER-ADMIN\""); + Header("HTTP/1.0 401 Unauthorized"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$PHP_AUTH_PW|$auth_message|\n"; + exit; + } + +if ($auth) + { + $office_no=strtoupper($PHP_AUTH_USER); + $password=strtoupper($PHP_AUTH_PW); + $auth_stmt="SELECT user_id,user,pass,full_name,user_level,user_group,phone_login,phone_pass,delete_users,delete_user_groups,delete_lists,delete_campaigns,delete_ingroups,delete_remote_agents,load_leads,campaign_detail,ast_admin_access,ast_delete_phones,delete_scripts,modify_leads,hotkeys_active,change_agent_campaign,agent_choose_ingroups,closer_campaigns,scheduled_callbacks,agentonly_callbacks,agentcall_manual,vicidial_recording,vicidial_transfers,delete_filters,alter_agent_interface_options,closer_default_blended,delete_call_times,modify_call_times,modify_users,modify_campaigns,modify_lists,modify_scripts,modify_filters,modify_ingroups,modify_usergroups,modify_remoteagents,modify_servers,view_reports,vicidial_recording_override,alter_custdata_override,qc_enabled,qc_user_level,qc_pass,qc_finish,qc_commit,add_timeclock_log,modify_timeclock_log,delete_timeclock_log,alter_custphone_override,vdc_agent_api_access,modify_inbound_dids,delete_inbound_dids,active,alert_enabled,download_lists,agent_shift_enforcement_override,manager_shift_enforcement_override,shift_override_flag,export_reports,delete_from_dnc,email,user_code,territory,allow_alerts,callcard_admin,force_change_password,modify_shifts,modify_phones,modify_carriers,modify_labels,modify_statuses,modify_voicemail,modify_audiostore,modify_moh,modify_tts,modify_contacts,modify_same_user_level from vicidial_users where user='$PHP_AUTH_USER';"; + $rslt=mysqli_query($link, $auth_stmt); + $row=mysqli_fetch_row($rslt); + $LOGfull_name =$row[3]; + $LOGuser_level =$row[4]; + $LOGuser_group =$row[5]; + $LOGdelete_users =$row[8]; + $LOGdelete_user_groups =$row[9]; + $LOGdelete_lists =$row[10]; + $LOGdelete_campaigns =$row[11]; + $LOGdelete_ingroups =$row[12]; + $LOGdelete_remote_agents =$row[13]; + $LOGload_leads =$row[14]; + $LOGcampaign_detail =$row[15]; + $LOGast_admin_access =$row[16]; + $LOGast_delete_phones =$row[17]; + $LOGdelete_scripts =$row[18]; + $LOGdelete_filters =$row[29]; + $LOGalter_agent_interface =$row[30]; + $LOGdelete_call_times =$row[32]; + $LOGmodify_call_times =$row[33]; + $LOGmodify_users =$row[34]; + $LOGmodify_campaigns =$row[35]; + $LOGmodify_lists =$row[36]; + $LOGmodify_scripts =$row[37]; + $LOGmodify_filters =$row[38]; + $LOGmodify_ingroups =$row[39]; + $LOGmodify_usergroups =$row[40]; + $LOGmodify_remoteagents =$row[41]; + $LOGmodify_servers =$row[42]; + $LOGview_reports =$row[43]; + $qc_auth =$row[46]; + $LOGmodify_dids =$row[56]; + $LOGdelete_dids =$row[57]; + $LOGmanager_shift_enforcement_override=$row[61]; + $LOGexport_reports =$row[64]; + $LOGdelete_from_dnc =$row[65]; + $LOGcallcard_admin =$row[70]; + $LOGforce_change_password =$row[71]; + $LOGmodify_shifts =$row[72]; + $LOGmodify_phones =$row[73]; + $LOGmodify_carriers =$row[74]; + $LOGmodify_labels =$row[75]; + $LOGmodify_statuses =$row[76]; + $LOGmodify_voicemail =$row[77]; + $LOGmodify_audiostore =$row[78]; + $LOGmodify_moh =$row[79]; + $LOGmodify_tts =$row[80]; + $LOGmodify_contacts =$row[81]; + $LOGmodify_same_user_level =$row[82]; + + $stmt="SELECT allowed_campaigns,allowed_reports,admin_viewable_groups,admin_viewable_call_times from vicidial_user_groups where user_group='$LOGuser_group';"; + $rslt=mysqli_query($link, $stmt); + $row=mysqli_fetch_row($rslt); + $LOGallowed_campaigns = $row[0]; + $LOGallowed_reports = $row[1]; + $LOGadmin_viewable_groups = $row[2]; + $LOGadmin_viewable_call_times = $row[3]; + } + +$stmt="SELECT allowed_campaigns,allowed_reports from vicidial_user_groups where user_group='$LOGuser_group';"; +if ($DB) {echo "|$stmt|\n";} +$rslt=mysqli_query($link, $stmt); +$row=mysqli_fetch_row($rslt); +$LOGallowed_campaigns = $row[0]; +$LOGallowed_reports = $row[1]; + +$LOGallowed_campaignsSQL=''; +$whereLOGallowed_campaignsSQL=''; +if ( (!preg_match("/ALL-/",$LOGallowed_campaigns)) ) + { + $rawLOGallowed_campaignsSQL = preg_replace("/ -/",'',$LOGallowed_campaigns); + $rawLOGallowed_campaignsSQL = preg_replace("/ /","','",$rawLOGallowed_campaignsSQL); + $LOGallowed_campaignsSQL = "and campaign_id IN('$rawLOGallowed_campaignsSQL')"; + $whereLOGallowed_campaignsSQL = "where campaign_id IN('$rawLOGallowed_campaignsSQL')"; + } +$regexLOGallowed_campaigns = " $LOGallowed_campaigns "; + +header ("Content-type: text/html; charset=utf-8"); +header ("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 +header ("Pragma: no-cache"); // HTTP/1.0 + +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo ""; +echo ""._QXZ("Quality control scorecards")."\n"; +echo "\n"; + +$NWB = "\"HELP\""; + + +##### BEGIN Set variables to make header show properly ##### +$ADD = '999998'; +$hh = 'qc'; +$qc_display_group_type = 'SCORECARD'; +$LOGast_admin_access = '1'; +$SSoutbound_autodial_active = '1'; +$ADMIN = 'admin.php'; +$page_width='770'; +$section_width='750'; +$header_font_size='3'; +$subheader_font_size='2'; +$subcamp_font_size='2'; +$header_selected_bold=''; +$header_nonselected_bold=''; +$admin_color = '#FFFF99'; +$admin_font = 'BLACK'; +$admin_color = '#E6E6E6'; +$subcamp_color = '#C6C6C6'; +##### END Set variables to make header show properly ##### + + +require("admin_header.php"); + +echo ""; + +?> + + +\n"; + echo ""; + + echo "\"Quality "._QXZ("Quality Control Scorecards").":

    \n"; + + if ($action=="delete_scorecard" && $scorecard_id && !$confirm_deletion) + { + echo ""._QXZ("CLICK HERE TO CONFIRM SCORECARD")." \"$scorecard_id\" "._QXZ("DELETION")."

    "; + } + else if ($action=="delete_scorecard" && $scorecard_id && $confirm_deletion=="Y") + { + $del_stmt="delete from quality_control_scorecards where qc_scorecard_id='$scorecard_id'"; + $del_rslt=mysql_to_mysqli($del_stmt, $link); + if(mysqli_affected_rows($link)>0) + { + echo ""._QXZ("SCORECARD")." $scorecard_id "._QXZ("DELETED")."

    "; + } + + + $del_stmt="delete from quality_control_checkpoints where qc_scorecard_id='$scorecard_id'"; + $del_rslt=mysql_to_mysqli($del_stmt, $link); + + } + echo "\n"; + echo "\n"; + echo "\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\t\n"; + echo "\t\n"; + # \n"; + echo "\t\t\t\n"; + + $qstmt="select count(*), sum(checkpoint_points) from quality_control_checkpoints where qc_scorecard_id='$row[qc_scorecard_id]'"; + $qrslt=mysql_to_mysqli($qstmt, $link); + $qrow=mysqli_fetch_row($qrslt); + $checkpoints=$qrow[0]; + ($checkpoints==0 ? $score_total="--" : $score_total=$qrow[1]); + echo "\t\t\t\n"; + echo "\t\t\t\n"; + + + $qstmt="select count(*) from vicidial_campaigns where qc_scorecard_id='$row[qc_scorecard_id]'"; + $qrslt=mysql_to_mysqli($qstmt, $link); + $qrow=mysqli_fetch_row($qrslt); + $campaigns_in_use=$qrow[0]; + + echo "\t\t\t\n"; + + + $qstmt="select count(*) from vicidial_inbound_groups where qc_scorecard_id='$row[qc_scorecard_id]'"; + $qrslt=mysql_to_mysqli($qstmt, $link); + $qrow=mysqli_fetch_row($qrslt); + $ingroups_in_use=$qrow[0]; + + echo "\t\t\t\n"; + + + $qstmt="select count(*) from vicidial_lists where qc_scorecard_id='$row[qc_scorecard_id]'"; + $qrslt=mysql_to_mysqli($qstmt, $link); + $qrow=mysqli_fetch_row($qrslt); + $lists_in_use=$qrow[0]; + + echo "\t\t\t\n"; + echo "\t\t\t\n"; + echo "\t\t\t\n"; + + echo "\t\t\t\n"; + echo "\t\t\t\n"; + echo ""; + } + echo "\t\n"; + echo "\t\t\n"; + echo "
    "._QXZ("Scorecard").""._QXZ("Checkpoints").""._QXZ("Pass/max score").""._QXZ("Campaigns").""._QXZ("In-groups").""._QXZ("Lists").""._QXZ("Last modified").""._QXZ("Active")."  
    $row[qc_scorecard_id] - $row[scorecard_name]$checkpoints$row[passing_score] / $score_total$campaigns_in_use$ingroups_in_use$lists_in_use$row[last_modified]
    \n"; + echo "\t
    \n"; + echo "
    \n"; + + echo "
    "; + echo ""; + + echo "\n"; + echo "\n"; + echo "
    \n"; + echo "\n"; + +echo "\n"; +echo "
    \n"; + +echo ""; +echo _QXZ("VERSION").": $admin_version
    "; +echo _QXZ("BUILD").": $build\n"; +if (!preg_match("/_BUILD_/",$SShosted_settings)) + {echo "
    © 2021 ViciDial Group
    ";} +echo "
    \n"; +echo "\n"; +echo "\n"; +echo "\n"; + +?> + + diff --git a/agc_2-X/trunk/www/vicidial/settings_compare.php b/agc_2-X/trunk/www/vicidial/settings_compare.php new file mode 100644 index 00000000..6febfd0f --- /dev/null +++ b/agc_2-X/trunk/www/vicidial/settings_compare.php @@ -0,0 +1,862 @@ + LICENSE: AGPLv2 +# +# CHANGES +# 210306-2052 - First build +# + +$startMS = microtime(); + +$report_name='Settings Compare'; + +require("dbconnect_mysqli.php"); +require("functions.php"); + +$PHP_AUTH_USER=$_SERVER['PHP_AUTH_USER']; +$PHP_AUTH_PW=$_SERVER['PHP_AUTH_PW']; +$PHP_SELF=$_SERVER['PHP_SELF']; +if (isset($_GET["DB"])) {$DB=$_GET["DB"];} + elseif (isset($_POST["DB"])) {$DB=$_POST["DB"];} +if (isset($_GET["first_id"])) {$first_id=$_GET["first_id"];} + elseif (isset($_POST["first_id"])) {$first_id=$_POST["first_id"];} +if (isset($_GET["second_id"])) {$second_id=$_GET["second_id"];} + elseif (isset($_POST["second_id"])) {$second_id=$_POST["second_id"];} +if (isset($_GET["stage"])) {$stage=$_GET["stage"];} + elseif (isset($_POST["stage"])) {$stage=$_POST["stage"];} +if (isset($_GET["submit"])) {$submit=$_GET["submit"];} + elseif (isset($_POST["submit"])) {$submit=$_POST["submit"];} +if (isset($_GET["SUBMIT"])) {$SUBMIT=$_GET["SUBMIT"];} + elseif (isset($_POST["SUBMIT"])) {$SUBMIT=$_POST["SUBMIT"];} + +############################################# +##### START SYSTEM_SETTINGS LOOKUP ##### +$stmt = "SELECT use_non_latin,webroot_writable,outbound_autodial_active,user_territories_active,enable_languages,language_method,allow_shared_dial,qc_features_active FROM system_settings;"; +$rslt=mysql_to_mysqli($stmt, $link); +if ($DB) {echo "$stmt\n";} +$qm_conf_ct = mysqli_num_rows($rslt); +if ($qm_conf_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $non_latin = $row[0]; + $webroot_writable = $row[1]; + $SSoutbound_autodial_active = $row[2]; + $user_territories_active = $row[3]; + $SSenable_languages = $row[4]; + $SSlanguage_method = $row[5]; + $SSallow_shared_dial = $row[6]; + $SSqc_features_active = $row[7]; + } +##### END SETTINGS LOOKUP ##### +########################################### + +$first_id = preg_replace('/[^-:\+\*\#\.\_0-9\p{L}]/u', '', $first_id); +$second_id = preg_replace('/[^-:\+\*\#\.\_0-9\p{L}]/u', '', $second_id); +$stage = preg_replace('/[^-_0-9a-zA-Z]/', '', $stage); + +if ($non_latin < 1) + { + $PHP_AUTH_USER = preg_replace('/[^-_0-9a-zA-Z]/', '', $PHP_AUTH_USER); + $PHP_AUTH_PW = preg_replace('/[^-_0-9a-zA-Z]/', '', $PHP_AUTH_PW); + } +else + { + $PHP_AUTH_PW = preg_replace("/'|\"|\\\\|;/","",$PHP_AUTH_PW); + $PHP_AUTH_USER = preg_replace("/'|\"|\\\\|;/","",$PHP_AUTH_USER); + } + +$stmt="SELECT selected_language from vicidial_users where user='$PHP_AUTH_USER';"; +if ($DB) {echo "|$stmt|\n";} +$rslt=mysql_to_mysqli($stmt, $link); +$sl_ct = mysqli_num_rows($rslt); +if ($sl_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $VUselected_language = $row[0]; + } + +$auth=0; +$reports_auth=0; +$admin_auth=0; +$auth_message = user_authorization($PHP_AUTH_USER,$PHP_AUTH_PW,'',1,0); +if ($auth_message == 'GOOD') + {$auth=1;} + +if ($auth > 0) + { + $stmt="SELECT count(*) from vicidial_users where user='$PHP_AUTH_USER' and user_level > 7 and view_reports='1';"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_row($rslt); + $admin_auth=$row[0]; + + $stmt="SELECT count(*) from vicidial_users where user='$PHP_AUTH_USER' and user_level > 6 and view_reports='1';"; + if ($DB) {echo "|$stmt|\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $row=mysqli_fetch_row($rslt); + $reports_auth=$row[0]; + + if ($reports_auth < 1) + { + $VDdisplayMESSAGE = _QXZ("You are not allowed to view reports"); + Header ("Content-type: text/html; charset=utf-8"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; + exit; + } + if ( ($reports_auth > 0) and ($admin_auth < 1) ) + { + $ADD=999999; + $reports_only_user=1; + } + } +else + { + $VDdisplayMESSAGE = _QXZ("Login incorrect, please try again"); + if ($auth_message == 'LOCK') + { + $VDdisplayMESSAGE = _QXZ("Too many login attempts, try again in 15 minutes"); + Header ("Content-type: text/html; charset=utf-8"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; + exit; + } + if ($auth_message == 'IPBLOCK') + { + $VDdisplayMESSAGE = _QXZ("Your IP Address is not allowed") . ": $ip"; + Header ("Content-type: text/html; charset=utf-8"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$auth_message|\n"; + exit; + } + Header("WWW-Authenticate: Basic realm=\"CONTACT-CENTER-ADMIN\""); + Header("HTTP/1.0 401 Unauthorized"); + echo "$VDdisplayMESSAGE: |$PHP_AUTH_USER|$PHP_AUTH_PW|$auth_message|\n"; + exit; + } + +$stmt="SELECT user_group,qc_enabled,modify_campaigns,modify_lists,modify_ingroups,modify_inbound_dids,modify_users,modify_usergroups,modify_phones,modify_servers,modify_shifts from vicidial_users where user='$PHP_AUTH_USER';"; +$rslt=mysql_to_mysqli($stmt, $link); +$row=mysqli_fetch_row($rslt); +$LOGuser_group = $row[0]; +$qc_auth = $row[1]; +$LOGmodify_campaigns = $row[2]; +$LOGmodify_lists = $row[3]; +$LOGmodify_ingroups = $row[4]; +$LOGmodify_inbound_dids = $row[5]; +$LOGmodify_users = $row[6]; +$LOGmodify_usergroups = $row[7]; +$LOGmodify_phones = $row[8]; +$LOGmodify_servers = $row[9]; +$LOGmodify_shifts = $row[10]; + +if ($LOGmodify_campaigns < 1) + { + Header ("Content-type: text/html; charset=utf-8"); + echo _QXZ("You do not have permissions for campaign debugging").": |$PHP_AUTH_USER|\n"; + exit; + } + +$stmt="SELECT allowed_campaigns,allowed_reports,admin_viewable_groups,admin_viewable_call_times from vicidial_user_groups where user_group='$LOGuser_group';"; +if ($DB) {$HTML_text.="|$stmt|\n";} +$rslt=mysql_to_mysqli($stmt, $link); +$row=mysqli_fetch_row($rslt); +$LOGallowed_campaigns = $row[0]; +$LOGallowed_reports = $row[1]; +$LOGadmin_viewable_groups = $row[2]; +$LOGadmin_viewable_call_times = $row[3]; + +$LOGallowed_campaignsSQL=''; +$whereLOGallowed_campaignsSQL=''; +if ( (!preg_match('/\-ALL/i', $LOGallowed_campaigns)) ) + { + $rawLOGallowed_campaignsSQL = preg_replace("/ -/",'',$LOGallowed_campaigns); + $rawLOGallowed_campaignsSQL = preg_replace("/ /","','",$rawLOGallowed_campaignsSQL); + $LOGallowed_campaignsSQL = "and campaign_id IN('$rawLOGallowed_campaignsSQL')"; + $whereLOGallowed_campaignsSQL = "where campaign_id IN('$rawLOGallowed_campaignsSQL')"; + } +$regexLOGallowed_campaigns = " $LOGallowed_campaigns "; + +$admin_viewable_groupsALL=0; +$LOGadmin_viewable_groupsSQL=''; +$whereLOGadmin_viewable_groupsSQL=''; +if ( (!preg_match('/\-\-ALL\-\-/i',$LOGadmin_viewable_groups)) and (strlen($LOGadmin_viewable_groups) > 3) ) + { + $rawLOGadmin_viewable_groupsSQL = preg_replace("/ -/",'',$LOGadmin_viewable_groups); + $rawLOGadmin_viewable_groupsSQL = preg_replace("/ /","','",$rawLOGadmin_viewable_groupsSQL); + $LOGadmin_viewable_groupsSQL = "and user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')"; + $whereLOGadmin_viewable_groupsSQL = "where user_group IN('---ALL---','$rawLOGadmin_viewable_groupsSQL')"; + } +else + {$admin_viewable_groupsALL=1;} + + +##### BEGIN log visit to the vicidial_report_log table ##### +$LOGip = getenv("REMOTE_ADDR"); +$LOGbrowser = getenv("HTTP_USER_AGENT"); +$LOGscript_name = getenv("SCRIPT_NAME"); +$LOGserver_name = getenv("SERVER_NAME"); +$LOGserver_port = getenv("SERVER_PORT"); +$LOGrequest_uri = getenv("REQUEST_URI"); +$LOGhttp_referer = getenv("HTTP_REFERER"); +$LOGbrowser=preg_replace("/\'|\"|\\\\/","",$LOGbrowser); +$LOGrequest_uri=preg_replace("/\'|\"|\\\\/","",$LOGrequest_uri); +$LOGhttp_referer=preg_replace("/\'|\"|\\\\/","",$LOGhttp_referer); +if (preg_match("/443/i",$LOGserver_port)) {$HTTPprotocol = 'https://';} + else {$HTTPprotocol = 'http://';} +if (($LOGserver_port == '80') or ($LOGserver_port == '443') ) {$LOGserver_port='';} +else {$LOGserver_port = ":$LOGserver_port";} +$LOGfull_url = "$HTTPprotocol$LOGserver_name$LOGserver_port$LOGrequest_uri"; + +$LOGhostname = php_uname('n'); +if (strlen($LOGhostname)<1) {$LOGhostname='X';} +if (strlen($LOGserver_name)<1) {$LOGserver_name='X';} + +$stmt="SELECT webserver_id FROM vicidial_webservers where webserver='$LOGserver_name' and hostname='$LOGhostname' LIMIT 1;"; +$rslt=mysql_to_mysqli($stmt, $link); +if ($DB) {echo "$stmt\n";} +$webserver_id_ct = mysqli_num_rows($rslt); +if ($webserver_id_ct > 0) + { + $row=mysqli_fetch_row($rslt); + $webserver_id = $row[0]; + } +else + { + ##### insert webserver entry + $stmt="INSERT INTO vicidial_webservers (webserver,hostname) values('$LOGserver_name','$LOGhostname');"; + if ($DB) {echo "$stmt\n";} + $rslt=mysql_to_mysqli($stmt, $link); + $affected_rows = mysqli_affected_rows($link); + $webserver_id = mysqli_insert_id($link); + } + +$stmt="INSERT INTO vicidial_report_log set event_date=NOW(), user='$PHP_AUTH_USER', ip_address='$LOGip', report_name='$report_name', browser='$LOGbrowser', referer='$LOGhttp_referer', notes='$LOGserver_name:$LOGserver_port $LOGscript_name', url='$LOGfull_url', webserver='$webserver_id';"; +if ($DB) {echo "|$stmt|\n";} +$rslt=mysql_to_mysqli($stmt, $link); +$report_log_id = mysqli_insert_id($link); +##### END log visit to the vicidial_report_log table ##### + +if ( (strlen($slave_db_server)>5) and (preg_match("/$report_name/",$reports_use_slave_db)) ) + { + mysqli_close($link); + $use_slave_server=1; + $db_source = 'S'; + require("dbconnect_mysqli.php"); + $MAIN.="\n"; + } + +$NOW_DATE = date("Y-m-d"); +$NOW_TIME = date("Y-m-d H:i:s"); +$STARTtime = date("U"); +if (!isset($query_date)) {$query_date = $NOW_DATE;} +if (!isset($server_ip)) {$server_ip = '10.10.10.15';} + +?> + + + + + +\n"; +echo "\n"; + +echo ""; + +$NWB = "\"HELP\""; + +$short_header=1; + +require("admin_header.php"); + +if ( ($stage == 'empty') or (strlen($stage) < 1) ) + { + echo "\n"; + echo ""._QXZ("Settings Compare Utility")."\n"; + echo "\n\n"; + echo "
    "; + echo "\n"; + echo _QXZ("Settings Compare Utility").$NWB."settings_compare".$NWE."

    \n"; + echo "
    \n"; + echo "\n"; + echo ""._QXZ("Settings Type").": "; + echo ""; + echo "   \n"; + echo "
    \n\n"; + echo "
    \n"; + echo "\n"; + exit; + } +else + { + echo "\n"; + echo ""._QXZ("Settings Compare Utility")."\n"; + echo "\n\n"; + echo "
    "; + echo "\n"; + echo _QXZ("Settings Compare Utility").$NWB."settings_compare".$NWE."         $stage         "._QXZ("RESET")."

    \n"; + + $first_id_menu=''; + $second_id_menu=''; + $stmt=''; + if ( ($stage == 'CAMPAIGNS') and ($LOGmodify_campaigns > 0) ) + {$stmt="SELECT campaign_id,campaign_name from vicidial_campaigns $whereLOGallowed_campaignsSQL order by campaign_id;";} + if ( ($stage == 'LISTS') and ($LOGmodify_lists > 0) ) + {$stmt="SELECT list_id,list_name from vicidial_lists $whereLOGallowed_campaignsSQL order by list_id;";} + if ( ($stage == 'IN-GROUPS') and ($LOGmodify_ingroups > 0) ) + {$stmt="SELECT group_id,group_name from vicidial_inbound_groups $whereLOGadmin_viewable_groupsSQL order by group_id;";} + if ( ($stage == 'DIDS') and ($LOGmodify_inbound_dids > 0) ) + {$stmt="SELECT did_pattern,did_description from vicidial_inbound_dids $whereLOGadmin_viewable_groupsSQL order by did_pattern;";} + if ( ($stage == 'CALLMENUS') and ($LOGmodify_inbound_dids > 0) ) + {$stmt="SELECT menu_id,menu_name from vicidial_call_menu $whereLOGadmin_viewable_groupsSQL order by menu_id;";} + if ( ($stage == 'USERS') and ($LOGmodify_users > 0) ) + {$stmt="SELECT user,full_name from vicidial_users $whereLOGadmin_viewable_groupsSQL order by user;";} + if ( ($stage == 'USER-GROUPS') and ($LOGmodify_usergroups > 0) ) + {$stmt="SELECT user_group,group_name from vicidial_user_groups $whereLOGadmin_viewable_groupsSQL order by user_group;";} + if ( ($stage == 'PHONES') and ($LOGmodify_phones > 0) ) + {$stmt="SELECT extension,server_ip from phones $whereLOGadmin_viewable_groupsSQL order by extension,server_ip;";} + if ( ($stage == 'SERVERS') and ($LOGmodify_servers > 0) ) + {$stmt="SELECT server_ip,server_description from servers $whereLOGadmin_viewable_groupsSQL order by server_ip;";} + if ( ($stage == 'SHIFTS') and ($LOGmodify_shifts > 0) ) + {$stmt="SELECT shift_id,shift_name from vicidial_shifts $whereLOGadmin_viewable_groupsSQL order by shift_id;";} + + if (strlen($stmt) > 10) + { + $rslt=mysql_to_mysqli($stmt, $link); + if ($DB) {echo "$stmt\n";} + $ids_to_print = mysqli_num_rows($rslt); + $first_found=0; + $first_text=''; + $second_found=0; + $second_text=''; + $i=0; + while ($ids_to_print > $i) + { + $row=mysqli_fetch_row($rslt); + $first_id_menu .= "$row[0] - $row[1]"; + } + else + { + if ($first_id == $row[0]) {$first_id_menu .= " SELECTED"; $first_found++;} + $first_id_menu .= " value=\"$row[0]\">$row[0] - $row[1]"; + } + + $second_id_menu .= "$row[0] - $row[1]"; + } + else + { + if ($second_id == $row[0]) {$second_id_menu .= " SELECTED"; $second_found++;} + $second_id_menu .= " value=\"$row[0]\">$row[0] - $row[1]"; + } + + + $i++; + } + if ($first_found < 1) {$first_id_menu .= "";} + if ($second_found < 1) {$second_id_menu .= "";} + + echo "\n\n"; + echo "
    "; + echo "
    \n"; + echo "\n"; + echo "\n"; + echo ""._QXZ("$stage")." 1: "; + echo ""; + echo "
    \n"; + echo ""._QXZ("$stage")." 2: "; + echo "   "; + echo "\n"; + echo "
    \n\n"; + echo "
    \n"; + + if ( (strlen($first_id) > 0) and (strlen($second_id) > 0) ) + { + $stmtA=''; $stmtAA=''; $countAA=''; $stmtAAA=''; $countAAA=''; $stmtAAAA=''; $countAAAA=''; $stmtAAAAA=''; $countAAAAA=''; + if ($stage == 'CAMPAIGNS') + { + $stmtA="SELECT * from vicidial_campaigns where campaign_id='$first_id' $LOGallowed_campaignsSQL;"; + $stmtAA="SELECT * from vicidial_campaign_statuses where campaign_id='$first_id' $LOGallowed_campaignsSQL order by status;"; + $countAA='campaign statuses'; + $stmtAAA="SELECT * from vicidial_campaign_hotkeys where campaign_id='$first_id' $LOGallowed_campaignsSQL order by hotkey;"; + $countAAA='campaign hotkeys'; + $stmtAAAA="SELECT * from vicidial_lead_recycle where campaign_id='$first_id' $LOGallowed_campaignsSQL order by status;"; + $countAAAA='campaign lead recycle'; + $stmtAAAAA="SELECT * from vicidial_pause_codes where campaign_id='$first_id' $LOGallowed_campaignsSQL order by pause_code;"; + $countAAAAA='campaign pause codes'; + } + if ($stage == 'LISTS') + { + $stmtA="SELECT * from vicidial_lists where list_id='$first_id' $LOGallowed_campaignsSQL;"; + $stmtAA="SELECT * from vicidial_lists_fields where list_id='$first_id' order by field_label;"; + $countAA='custom list fields'; + } + if ($stage == 'IN-GROUPS') {$stmtA="SELECT * from vicidial_inbound_groups where group_id='$first_id' $LOGadmin_viewable_groupsSQL;";} + if ($stage == 'DIDS') {$stmtA="SELECT * from vicidial_inbound_dids where did_pattern='$first_id' $LOGadmin_viewable_groupsSQL;";} + if ($stage == 'CALLMENUS') + { + $stmtA="SELECT * from vicidial_call_menu where menu_id='$first_id' $LOGadmin_viewable_groupsSQL;"; + $stmtAA="SELECT * from vicidial_call_menu_options where menu_id='$first_id' order by option_value limit 20;"; + $countAA='options'; + } + if ($stage == 'USERS') + { + $stmtA="SELECT * from vicidial_users where user='$first_id' $LOGadmin_viewable_groupsSQL;"; + $stmtAA="SELECT * from vicidial_campaign_agents where user='$first_id' order by campaign_id limit 1000;"; + $countAA='user campaign settings'; + $stmtAAA="SELECT * from vicidial_inbound_group_agents where user='$first_id' order by group_id limit 1000;"; + $countAAA='user in-group settings'; + } + if ($stage == 'USER-GROUPS') {$stmtA="SELECT * from vicidial_user_groups where user_group='$first_id' $LOGadmin_viewable_groupsSQL;";} + if ($stage == 'PHONES') + { + $first_id_ARY = explode('-----',$first_id); + $stmtA="SELECT * from phones where extension='$first_id_ARY[0]'and server_ip='$first_id_ARY[1]' $LOGadmin_viewable_groupsSQL;"; + } + if ($stage == 'SERVERS') {$stmtA="SELECT * from servers where server_ip='$first_id' $LOGadmin_viewable_groupsSQL;";} + if ($stage == 'SHIFTS') {$stmtA="SELECT * from vicidial_shifts where shift_id='$first_id' $LOGadmin_viewable_groupsSQL;";} + + + $stmtB=''; $stmtBB=''; $countBB=''; $stmtBBB=''; $countBBB=''; $stmtBBBB=''; $countBBBB=''; + if ($stage == 'CAMPAIGNS') + { + $stmtB="SELECT * from vicidial_campaigns where campaign_id='$second_id' $LOGallowed_campaignsSQL;"; + $stmtBB="SELECT * from vicidial_campaign_statuses where campaign_id='$second_id' $LOGallowed_campaignsSQL order by status;"; + $countBB='campaign statuses'; + $stmtBBB="SELECT * from vicidial_campaign_hotkeys where campaign_id='$second_id' $LOGallowed_campaignsSQL order by hotkey;"; + $countBBB='campaign hotkeys'; + $stmtBBBB="SELECT * from vicidial_lead_recycle where campaign_id='$second_id' $LOGallowed_campaignsSQL order by status;"; + $countBBBB='campaign lead recycle'; + $stmtBBBBB="SELECT * from vicidial_pause_codes where campaign_id='$second_id' $LOGallowed_campaignsSQL order by pause_code;"; + $countBBBBB='campaign pause codes'; + } + if ($stage == 'LISTS') + { + $stmtB="SELECT * from vicidial_lists where list_id='$second_id' $LOGallowed_campaignsSQL;"; + $stmtBB="SELECT * from vicidial_lists_fields where list_id='$second_id' order by field_label;"; + $countBB='custom list fields'; + } + if ($stage == 'IN-GROUPS') {$stmtB="SELECT * from vicidial_inbound_groups where group_id='$second_id' $LOGadmin_viewable_groupsSQL;";} + if ($stage == 'DIDS') {$stmtB="SELECT * from vicidial_inbound_dids where did_pattern='$second_id' $LOGadmin_viewable_groupsSQL;";} + if ($stage == 'CALLMENUS') + { + $stmtB="SELECT * from vicidial_call_menu where menu_id='$second_id' $LOGadmin_viewable_groupsSQL;"; + $stmtBB="SELECT * from vicidial_call_menu_options where menu_id='$second_id' order by option_value limit 20;"; + $countBB='options'; + } + if ($stage == 'USERS') + { + $stmtB="SELECT * from vicidial_users where user='$second_id' $LOGadmin_viewable_groupsSQL;"; + $stmtBB="SELECT * from vicidial_campaign_agents where user='$second_id' order by campaign_id limit 1000;"; + $countBB='user campaign settings'; + $stmtBBB="SELECT * from vicidial_inbound_group_agents where user='$second_id' order by group_id limit 1000;"; + $countBBB='user in-group settings'; + } + if ($stage == 'USER-GROUPS') {$stmtB="SELECT * from vicidial_user_groups where user_group='$second_id' $LOGadmin_viewable_groupsSQL;";} + if ($stage == 'PHONES') + { + $second_id_ARY = explode('-----',$second_id); + $stmtB="SELECT * from phones where extension='$second_id_ARY[0]'and server_ip='$second_id_ARY[1]' $LOGadmin_viewable_groupsSQL;"; + } + if ($stage == 'SERVERS') {$stmtB="SELECT * from servers where server_ip='$second_id' $LOGadmin_viewable_groupsSQL;";} + if ($stage == 'SHIFTS') {$stmtB="SELECT * from vicidial_shifts where shift_id='$second_id' $LOGadmin_viewable_groupsSQL;";} + + if ( (strlen($stmtA) > 10) and (strlen($stmtB) > 10) ) + { + $rslt=mysql_to_mysqli($stmtA, $link); + if ($DB) {echo "$stmtA\n";} + $ids_to_print = mysqli_num_rows($rslt); + $i=0; + while ($ids_to_print > $i) + { + $row = mysqli_fetch_array($rslt); + for($j = 0; $j < mysqli_num_fields($rslt); $j++) + { + $field_info = mysqli_fetch_field($rslt); + $col = "{$field_info->name}"; + if ($col != 'pass_hash') + {$first_text .= $col . "='" . $row[$col] . "' \n";} + } + $i++; + } + + $rslt=mysql_to_mysqli($stmtB, $link); + if ($DB) {echo "$stmtB\n";} + $ids_to_print = mysqli_num_rows($rslt); + $i=0; + while ($ids_to_print > $i) + { + $row = mysqli_fetch_array($rslt); + for($j = 0; $j < mysqli_num_fields($rslt); $j++) + { + $field_info = mysqli_fetch_field($rslt); + $col = "{$field_info->name}"; + if ($col != 'pass_hash') + {$second_text .= $col . "='" . $row[$col] . "' \n";} + } + $i++; + } + + ### list first sub-entries, if defined + if (strlen($stmtAA) > 10) + { + $rslt=mysql_to_mysqli($stmtAA, $link); + if ($DB) {echo "$stmtAA\n";} + $ids_to_print = mysqli_num_rows($rslt); + $first_text .= $countAA . " section start \n"; + $first_text .= $countAA . "='" . $ids_to_print . "' \n"; + $i=0; + $field_name_ARY=array(); + while ( ($ids_to_print > $i) and ($i < 1000) ) + { + $row = mysqli_fetch_array($rslt); + $fields = mysqli_num_fields($rslt); + if ($i==0) + { + for($j = 0; $j < mysqli_num_fields($rslt); $j++) + { + $field_info = mysqli_fetch_field($rslt); + $field_name_ARY[$j] = "{$field_info->name}"; + } + } + $j=0; + while($fields > $j) + { + $col=$field_name_ARY[$j]; + $value=$row[$j]; + if ($col != 'pass_hash') + {$first_text .= $col . "='" . $value . "' \n";} + if ($DB) {echo "$i Fields: $fields|J: $j|col: $col|value: $value\n";} + $j++; + } + $i++; + } + } + if (strlen($stmtBB) > 10) + { + $rslt=mysql_to_mysqli($stmtBB, $link); + if ($DB) {echo "$stmtBB\n";} + $ids_to_print = mysqli_num_rows($rslt); + $second_text .= $countBB . " section start \n"; + $second_text .= $countBB . "='" . $ids_to_print . "' \n"; + $i=0; + $field_name_ARY=array(); + while ( ($ids_to_print > $i) and ($i < 1000) ) + { + $row = mysqli_fetch_array($rslt); + $fields = mysqli_num_fields($rslt); + if ($i==0) + { + for($j = 0; $j < mysqli_num_fields($rslt); $j++) + { + $field_info = mysqli_fetch_field($rslt); + $field_name_ARY[$j] = "{$field_info->name}"; + } + } + $j=0; + while($fields > $j) + { + $col=$field_name_ARY[$j]; + $value=$row[$j]; + if ($col != 'pass_hash') + {$second_text .= $col . "='" . $value . "' \n";} + if ($DB) {echo "$i Fields: $fields|J: $j|col: $col|value: $value\n";} + $j++; + } + $i++; + } + } + + ### list second sub-entries, if defined + if (strlen($stmtAAA) > 10) + { + $rslt=mysql_to_mysqli($stmtAAA, $link); + if ($DB) {echo "$stmtAAA\n";} + $ids_to_print = mysqli_num_rows($rslt); + $first_text .= $countAAA . " section start \n"; + $first_text .= $countAAA . "='" . $ids_to_print . "' \n"; + $i=0; + $field_name_ARY=array(); + while ( ($ids_to_print > $i) and ($i < 1000) ) + { + $row = mysqli_fetch_array($rslt); + $fields = mysqli_num_fields($rslt); + if ($i==0) + { + for($j = 0; $j < mysqli_num_fields($rslt); $j++) + { + $field_info = mysqli_fetch_field($rslt); + $field_name_ARY[$j] = "{$field_info->name}"; + } + } + $j=0; + while($fields > $j) + { + $col=$field_name_ARY[$j]; + $value=$row[$j]; + if ($col != 'pass_hash') + {$first_text .= $col . "='" . $value . "' \n";} + if ($DB) {echo "$i Fields: $fields|J: $j|col: $col|value: $value\n";} + $j++; + } + $i++; + } + } + if (strlen($stmtBBB) > 10) + { + $rslt=mysql_to_mysqli($stmtBBB, $link); + if ($DB) {echo "$stmtBBB\n";} + $ids_to_print = mysqli_num_rows($rslt); + $second_text .= $countBBB . " section start \n"; + $second_text .= $countBBB . "='" . $ids_to_print . "' \n"; + $i=0; + $field_name_ARY=array(); + while ( ($ids_to_print > $i) and ($i < 1000) ) + { + $row = mysqli_fetch_array($rslt); + $fields = mysqli_num_fields($rslt); + if ($i==0) + { + for($j = 0; $j < mysqli_num_fields($rslt); $j++) + { + $field_info = mysqli_fetch_field($rslt); + $field_name_ARY[$j] = "{$field_info->name}"; + } + } + $j=0; + while($fields > $j) + { + $col=$field_name_ARY[$j]; + $value=$row[$j]; + if ($col != 'pass_hash') + {$second_text .= $col . "='" . $value . "' \n";} + if ($DB) {echo "$i Fields: $fields|J: $j|col: $col|value: $value\n";} + $j++; + } + $i++; + } + } + + ### list third sub-entries, if defined + if (strlen($stmtAAAA) > 10) + { + $rslt=mysql_to_mysqli($stmtAAAA, $link); + if ($DB) {echo "$stmtAAAA\n";} + $ids_to_print = mysqli_num_rows($rslt); + $first_text .= $countAAAA . " section start \n"; + $first_text .= $countAAAA . "='" . $ids_to_print . "' \n"; + $i=0; + $field_name_ARY=array(); + while ( ($ids_to_print > $i) and ($i < 1000) ) + { + $row = mysqli_fetch_array($rslt); + $fields = mysqli_num_fields($rslt); + if ($i==0) + { + for($j = 0; $j < mysqli_num_fields($rslt); $j++) + { + $field_info = mysqli_fetch_field($rslt); + $field_name_ARY[$j] = "{$field_info->name}"; + } + } + $j=0; + while($fields > $j) + { + $col=$field_name_ARY[$j]; + $value=$row[$j]; + if ($col != 'pass_hash') + {$first_text .= $col . "='" . $value . "' \n";} + if ($DB) {echo "$i Fields: $fields|J: $j|col: $col|value: $value\n";} + $j++; + } + $i++; + } + } + if (strlen($stmtBBBB) > 10) + { + $rslt=mysql_to_mysqli($stmtBBBB, $link); + if ($DB) {echo "$stmtBBBB\n";} + $ids_to_print = mysqli_num_rows($rslt); + $second_text .= $countBBBB . " section start \n"; + $second_text .= $countBBBB . "='" . $ids_to_print . "' \n"; + $i=0; + $field_name_ARY=array(); + while ( ($ids_to_print > $i) and ($i < 1000) ) + { + $row = mysqli_fetch_array($rslt); + $fields = mysqli_num_fields($rslt); + if ($i==0) + { + for($j = 0; $j < mysqli_num_fields($rslt); $j++) + { + $field_info = mysqli_fetch_field($rslt); + $field_name_ARY[$j] = "{$field_info->name}"; + } + } + $j=0; + while($fields > $j) + { + $col=$field_name_ARY[$j]; + $value=$row[$j]; + if ($col != 'pass_hash') + {$second_text .= $col . "='" . $value . "' \n";} + if ($DB) {echo "$i Fields: $fields|J: $j|col: $col|value: $value\n";} + $j++; + } + $i++; + } + } + + ### list fourth sub-entries, if defined + if (strlen($stmtAAAAA) > 10) + { + $rslt=mysql_to_mysqli($stmtAAAAA, $link); + if ($DB) {echo "$stmtAAAAA\n";} + $ids_to_print = mysqli_num_rows($rslt); + $first_text .= $countAAAAA . " section start \n"; + $first_text .= $countAAAAA . "='" . $ids_to_print . "' \n"; + $i=0; + $field_name_ARY=array(); + while ( ($ids_to_print > $i) and ($i < 1000) ) + { + $row = mysqli_fetch_array($rslt); + $fields = mysqli_num_fields($rslt); + if ($i==0) + { + for($j = 0; $j < mysqli_num_fields($rslt); $j++) + { + $field_info = mysqli_fetch_field($rslt); + $field_name_ARY[$j] = "{$field_info->name}"; + } + } + $j=0; + while($fields > $j) + { + $col=$field_name_ARY[$j]; + $value=$row[$j]; + if ($col != 'pass_hash') + {$first_text .= $col . "='" . $value . "' \n";} + if ($DB) {echo "$i Fields: $fields|J: $j|col: $col|value: $value\n";} + $j++; + } + $i++; + } + } + if (strlen($stmtBBBBB) > 10) + { + $rslt=mysql_to_mysqli($stmtBBBBB, $link); + if ($DB) {echo "$stmtBBBBB\n";} + $ids_to_print = mysqli_num_rows($rslt); + $second_text .= $countBBBBB . " section start \n"; + $second_text .= $countBBBBB . "='" . $ids_to_print . "' \n"; + $i=0; + $field_name_ARY=array(); + while ( ($ids_to_print > $i) and ($i < 1000) ) + { + $row = mysqli_fetch_array($rslt); + $fields = mysqli_num_fields($rslt); + if ($i==0) + { + for($j = 0; $j < mysqli_num_fields($rslt); $j++) + { + $field_info = mysqli_fetch_field($rslt); + $field_name_ARY[$j] = "{$field_info->name}"; + } + } + $j=0; + while($fields > $j) + { + $col=$field_name_ARY[$j]; + $value=$row[$j]; + if ($col != 'pass_hash') + {$second_text .= $col . "='" . $value . "' \n";} + if ($DB) {echo "$i Fields: $fields|J: $j|col: $col|value: $value\n";} + $j++; + } + $i++; + } + } + + // include the Diff class + require_once './class.Diff.php'; + + echo Diff::toTable(Diff::compare($first_text, $second_text)); + } + } + } + else + { + echo _QXZ("Please click RESET to start over").": "._QXZ("RESET")."

    \n"; + exit; + } + echo "
    \n"; + echo ""; + } +exit;