From 892525d80fed694b82fea19411289dda85f56d30 Mon Sep 17 00:00:00 2001 From: Adam Zammit Date: Tue, 28 Jan 2014 14:58:05 +1100 Subject: [PATCH 1/9] New tables created for complex quotas Conversion of code to handle new schema begun --- CHANGELOG | 33 +++++++++++++++++++++++++++++ admin/questionnairelist.php | 16 +++++++++++++++ admin/quotareport.php | 27 ++++++++++++++++++------ admin/quotarow.php | 40 +++++++++++------------------------- admin/samplecallattempts.php | 20 +++++++++++++++--- database/quexs.sql | 31 ++++++++++++++++++++++++++++ 6 files changed, 130 insertions(+), 37 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6943474c..968c2b78 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,36 @@ +CREATE TABLE `qsqr_question` ( + `qsqr_question_id` bigint(20) NOT NULL AUTO_INCREMENT, + `questionnaire_sample_quota_row_id` bigint(20) NOT NULL, + `lime_sgqa` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `value` varchar(2048) COLLATE utf8_unicode_ci NOT NULL, + `comparison` varchar(15) COLLATE utf8_unicode_ci NOT NULL, + `description` text COLLATE utf8_unicode_ci NOT NULL, + PRIMARY KEY (`qsqr_question_id`), + KEY `questionnaire_sample_quota_row_id` (`questionnaire_sample_quota_row_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; + +CREATE TABLE `qsqr_sample` ( + `qsqr_sample_id` bigint(20) NOT NULL AUTO_INCREMENT, + `questionnaire_sample_quota_row_id` bigint(20) NOT NULL, + `exclude_var` char(128) COLLATE utf8_unicode_ci NOT NULL, + `exclude_val` varchar(256) COLLATE utf8_unicode_ci NOT NULL, + `comparison` varchar(15) COLLATE utf8_unicode_ci NOT NULL, + `description` text COLLATE utf8_unicode_ci NOT NULL, + PRIMARY KEY (`qsqr_sample_id`), + KEY `questionnaire_sample_quota_row_id` (`questionnaire_sample_quota_row_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; + + +INSERT INTO qsqr_question (questionnaire_sample_quota_row_id,lime_sgqa,value,comparison) +SELECT questionnaire_sample_quota_row_id, lime_sgqa, value, comparison +FROM questionnaire_sample_quota_row; + +INSERT INTO qsqr_sample (questionnaire_sample_quota_row_id,exclude_var,exclude_val,comparison) +SELECT questionnaire_sample_quota_row_id, exclude_var,exclude_val, 'LIKE' +FROM questionnaire_sample_quota_row; + + + queXS 1.10.0 - Changes since 1.9.2 New Feature: Operators can choose extension (see: https://blueprints.launchpad.net/quexs/+spec/operatorextension) diff --git a/admin/questionnairelist.php b/admin/questionnairelist.php index b8a01b0f..4a2b0bf1 100644 --- a/admin/questionnairelist.php +++ b/admin/questionnairelist.php @@ -158,6 +158,22 @@ if (isset($_POST['questionnaire_id']) && isset($_POST['submit'])) $db->Execute($sql); + $sql = "DELETE FROM qsqr_question + WHERE questionnaire_sample_quota_row_id IN ( + SELECT questionnaire_sample_quota_row_id + FROM questionnaire_sample_quota_row + WHERE questionnaire_id = $questionnaire_id)"; + + $db->Execute($sql); + + $sql = "DELETE FROM qsqr_sample + WHERE questionnaire_sample_quota_row_id IN ( + SELECT questionnaire_sample_quota_row_id + FROM questionnaire_sample_quota_row + WHERE questionnaire_id = $questionnaire_id)"; + + $db->Execute($sql); + $sql = "DELETE FROM `questionnaire_sample_quota_row` WHERE questionnaire_id = $questionnaire_id"; diff --git a/admin/quotareport.php b/admin/quotareport.php index 3004ccc3..bf2ddbe5 100644 --- a/admin/quotareport.php +++ b/admin/quotareport.php @@ -179,11 +179,12 @@ if ($questionnaire_id) //a. (Standard quota) Monitor outcomes of questions in completed questionnaires, and exclude selected sample records when completion limit is reached //b. (Replicate quota) Exclude selected sample records (where lime_sgqa == -1) - $sql = "SELECT questionnaire_sample_quota_row_id,lime_sgqa,value,completions,quota_reached,lime_sid,comparison,exclude_var,exclude_val,qsq.description,current_completions, priority, autoprioritise - FROM questionnaire_sample_quota_row as qsq, questionnaire as q + $sql = "SELECT questionnaire_sample_quota_row_id,qsqr_question.lime_sgqa,value,completions,quota_reached,lime_sid,qsq.description,current_completions, priority, autoprioritise + FROM questionnaire_sample_quota_row as qsq, questionnaire as q, qsqr_question WHERE qsq.questionnaire_id = '$questionnaire_id' AND qsq.sample_import_id = '$sample_import_id' - AND q.questionnaire_id = '$questionnaire_id'"; + AND q.questionnaire_id = '$questionnaire_id' + AND qsqr_question.questionnaire_sample_quota_row_id = qsq.questionnaire_sample_quota_row_id"; $r = $db->GetAll($sql); @@ -210,9 +211,23 @@ if ($questionnaire_id) //We need to calc Sample size, Sample drawn, Sample remain $sql = "SELECT (c.sample_id is not null) as type, count(*) as count FROM sample as s - JOIN questionnaire_sample as qs ON (qs.questionnaire_id = '$questionnaire_id' and qs.sample_import_id = s.import_id) - JOIN sample_var as sv ON (sv.sample_id = s.sample_id AND sv.var LIKE '{$v['exclude_var']}' AND sv.val LIKE '{$v['exclude_val']}') - LEFT JOIN `case` as c ON (c.questionnaire_id = qs.questionnaire_id and c.sample_id = s.sample_id) + JOIN questionnaire_sample as qs ON (qs.questionnaire_id = '$questionnaire_id' and qs.sample_import_id = s.import_id) "; + + $sql2 = "SELECT exclude_val,exclude_var,comparison + FROM qsqr_sample + WHERE questionnaire_sample_quota_row_id = {$v['questionnaire_sample_quota_row_id']}"; + + $rev = $db->GetAll($sql2); + + //reduce sample by every item in the qsqr_sample table + $x = 1; + foreach($rev as $ev) + { + $sql .= " JOIN sample_var as sv$x ON (sv$x.sample_id = s.sample_id AND sv$x.var LIKE '{$ev['exclude_var']}' AND sv$x.val {$ev['comparison']} '{$ev['exclude_val']}') "; + $x++; + } + + $sql .= " LEFT JOIN `case` as c ON (c.questionnaire_id = qs.questionnaire_id and c.sample_id = s.sample_id) WHERE s.import_id = '$sample_import_id' GROUP BY (c.sample_id is not null)"; diff --git a/admin/quotarow.php b/admin/quotarow.php index b4f3fced..5544a963 100755 --- a/admin/quotarow.php +++ b/admin/quotarow.php @@ -112,12 +112,12 @@ if (isset($_GET['questionnaire_id']) && isset($_GET['sgqa']) && isset($_GET['va if (isset($_GET['questionnaire_id']) && isset($_GET['questionnaire_sample_quota_row_id'])) { - //need to remove quota + //need to edit quota $questionnaire_id = bigintval($_GET['questionnaire_id']); $questionnaire_sample_quota_row_id = bigintval($_GET['questionnaire_sample_quota_row_id']); - open_row_quota($questionnaire_sample_quota_row_id); + //open_row_quota($questionnaire_sample_quota_row_id); } $questionnaire_id = false; @@ -160,9 +160,9 @@ if ($questionnaire_id != false) print "

" . T_("Copied quotas") . "

"; } - print "

" . T_("Current row quotas (click to delete)") . "

"; + print "

" . T_("Current row quotas (click to edit)") . "

"; - $sql = "SELECT questionnaire_sample_quota_row_id,lime_sgqa,value,completions,quota_reached,lime_sid,comparison,exclude_var,exclude_val,current_completions + $sql = "SELECT questionnaire_sample_quota_row_id,qsq.description FROM questionnaire_sample_quota_row as qsq, questionnaire as q WHERE qsq.questionnaire_id = '$questionnaire_id' AND qsq.sample_import_id = '$sample_import_id' @@ -177,7 +177,12 @@ if ($questionnaire_id != false) else { foreach($r as $v) - { + { + print "
" . $v['description'] . ""; + + } + /* + if ($v['lime_sgqa'] == -1) print "
" . T_("Replicate: Where") . " " . $v['exclude_var'] . " " . T_("like") . " " . $v['exclude_val'] . " - "; else if ($v['lime_sgqa'] == -2) @@ -197,30 +202,9 @@ if ($questionnaire_id != false) print "
"; } + */ - - $sql = "SELECT s.sample_import_id as value,s.description, '' AS selected - FROM sample_import as s, questionnaire_sample as q - WHERE q.questionnaire_id = $questionnaire_id - AND q.sample_import_id = s.sample_import_id - AND s.sample_import_id != '$sample_import_id'"; - - $ss = $db->GetAll($sql); - - if (!empty($ss)) - { - print "

" . T_("Copy quotas for this sample to (No error/duplicate checking): "); - display_chooser($ss,"copy_sample_import_id","copy_sample_import_id",false,false,false,false); - print "

"; - - print "

" . T_("Copy quotas for this sample to (No error/duplicate checking) with adjusting: "); - display_chooser($ss,"copy_sample_import_id_with_adjustment","copy_sample_import_id_with_adjustment",false,false,false,false); - print "

"; - } - - } - - + //new quota print "

" . T_("Select a question for the row quota") . "

"; $sql = "SELECT lime_sid diff --git a/admin/samplecallattempts.php b/admin/samplecallattempts.php index 8a37abb5..2be2415c 100644 --- a/admin/samplecallattempts.php +++ b/admin/samplecallattempts.php @@ -77,9 +77,23 @@ function sample_call_attempt_report($questionnaire_id = false, $sample_id = fals $s = "JOIN sample as s ON (s.sample_id = c.sample_id AND s.import_id = '$sample_id')"; $qs = ""; - if ($qsqri !== false) - $qs = "JOIN questionnaire_sample_quota_row as q ON (q.questionnaire_sample_quota_row_id = '$qsqri') - JOIN sample_var ON (sample_var.sample_id = c.sample_id AND sample_var.var LIKE q.exclude_var AND sample_var.val LIKE q.exclude_val)"; + + if ($qsqri !== false) + { + $sql2 = "SELECT exclude_val,exclude_var,comparison + FROM qsqr_sample + WHERE questionnaire_sample_quota_row_id = $qsqri"; + + $rev = $db->GetAll($sql2); + + //reduce sample by every item in the qsqr_sample table + $x = 1; + foreach($rev as $ev) + { + $qs .= " JOIN sample_var as sv$x ON (sv$x.sample_id = c.sample_id AND sv$x.var LIKE '{$ev['exclude_var']}' AND sv$x.val {$ev['comparison']} '{$ev['exclude_val']}') "; + $x++; + } + } $sql = "SELECT ca1 AS callattempts, COUNT( ca1 ) AS sample FROM ( SELECT count( ca.call_attempt_id ) AS ca1 diff --git a/database/quexs.sql b/database/quexs.sql index bf50273b..5c82f807 100644 --- a/database/quexs.sql +++ b/database/quexs.sql @@ -1362,8 +1362,39 @@ CREATE TABLE `process_log` ( -- +-- Table structure for table `qsqr_question` +-- +-- + +CREATE TABLE `qsqr_question` ( + `qsqr_question_id` bigint(20) NOT NULL AUTO_INCREMENT, + `questionnaire_sample_quota_row_id` bigint(20) NOT NULL, + `lime_sgqa` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `value` varchar(2048) COLLATE utf8_unicode_ci NOT NULL, + `comparison` varchar(15) COLLATE utf8_unicode_ci NOT NULL, + `description` text COLLATE utf8_unicode_ci NOT NULL, + PRIMARY KEY (`qsqr_question_id`), + KEY `questionnaire_sample_quota_row_id` (`questionnaire_sample_quota_row_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; + -- -------------------------------------------------------- +-- +-- Table structure for table `qsqr_sample` +-- + +CREATE TABLE `qsqr_sample` ( + `qsqr_sample_id` bigint(20) NOT NULL AUTO_INCREMENT, + `questionnaire_sample_quota_row_id` bigint(20) NOT NULL, + `exclude_var` char(128) COLLATE utf8_unicode_ci NOT NULL, + `exclude_val` varchar(256) COLLATE utf8_unicode_ci NOT NULL, + `comparison` varchar(15) COLLATE utf8_unicode_ci NOT NULL, + `description` text COLLATE utf8_unicode_ci NOT NULL, + PRIMARY KEY (`qsqr_sample_id`), + KEY `questionnaire_sample_quota_row_id` (`questionnaire_sample_quota_row_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; + + -- -- Table structure for table `questionnaire` -- From c142c24ef05dabbe8311ffe1475ce2d70ae6b523 Mon Sep 17 00:00:00 2001 From: Adam Zammit Date: Fri, 31 Jan 2014 14:37:49 +1100 Subject: [PATCH 2/9] Updated quota functions to handle new structure and concept --- functions/functions.operator.php | 236 ++++++++++++++++++++++++------- nocaseavailable.php | 7 +- 2 files changed, 190 insertions(+), 53 deletions(-) diff --git a/functions/functions.operator.php b/functions/functions.operator.php index 6d68dd60..05692704 100644 --- a/functions/functions.operator.php +++ b/functions/functions.operator.php @@ -1463,6 +1463,17 @@ function open_row_quota($questionnaire_sample_quota_row_id,$delete = true) WHERE questionnaire_sample_quota_row_id = '$questionnaire_sample_quota_row_id'"; $db->Execute($sql); + + $sql = "DELETE FROM qsqr_sample + WHERE questionnaire_sample_quota_row_id = '$questionnaire_sample_quota_row_id'"; + + $db->Execute($sql); + + $sql = "DELETE FROM qsqr_question + WHERE questionnaire_sample_quota_row_id = '$questionnaire_sample_quota_row_id'"; + + $db->Execute($sql); + } $sql = "DELETE FROM questionnaire_sample_quota_row_exclude @@ -1503,16 +1514,28 @@ function close_row_quota($questionnaire_sample_quota_row_id,$update = true) $rs = $db->GetRow($sql); if (isset($coun['c']) && $coun['c'] == 0) - { - //store list of sample records to exclude - $sql = "INSERT INTO questionnaire_sample_quota_row_exclude (questionnaire_sample_quota_row_id,questionnaire_id,sample_id) - SELECT $questionnaire_sample_quota_row_id,qs.questionnaire_id,s.sample_id - FROM sample as s, sample_var as sv, questionnaire_sample_quota_row as qs - WHERE s.import_id = qs.sample_import_id - AND qs.questionnaire_sample_quota_row_id = $questionnaire_sample_quota_row_id - AND s.sample_id = sv.sample_id - AND sv.var = qs.exclude_var - AND qs.exclude_val LIKE sv.val"; + { + $sql2 = "SELECT exclude_val,exclude_var,comparison + FROM qsqr_sample + WHERE questionnaire_sample_quota_row_id = $questionnaire_sample_quota_row_id"; + + $rev = $db->GetAll($sql2); + + //store list of sample records to exclude + $sql = "INSERT INTO questionnaire_sample_quota_row_exclude (questionnaire_sample_quota_row_id,questionnaire_id,sample_id) + SELECT $questionnaire_sample_quota_row_id,qs.questionnaire_id,s.sample_id + FROM sample as s "; + + //reduce sample by every item in the qsqr_sample table + $x = 1; + foreach($rev as $ev) + { + $sql .= " JOIN sample_var as sv$x ON (sv$x.sample_id = s.sample_id AND sv$x.var LIKE '{$ev['exclude_var']}' AND sv$x.val {$ev['comparison']} '{$ev['exclude_val']}') "; + $x++; + } + + $sql = "JOIN questionnaire_sample_quota_row as qs ON (qs.questionnaire_sample_quota_row_id = $questionnaire_sample_quota_row_id) + WHERE s.import_id = qs.sample_import_id"; $db->Execute($sql); @@ -1536,22 +1559,35 @@ function close_row_quota($questionnaire_sample_quota_row_id,$update = true) * @param int $questionnaire_id * @param int $sample_import_id * @param int $copy_sample_import_id The sample_import_id to copy to + * @param bool $blocking Block (copy quota)? */ -function copy_row_quota($questionnaire_id,$sample_import_id,$copy_sample_import_id) +function copy_row_quota($questionnaire_id,$sample_import_id,$copy_sample_import_id, $block = false) { global $db; $db->StartTrans(); - //Set quota_reached to 0 always + //Set quota_reached to 0 always if not blocking + $b = 0; + if ($block == true) + $b = "quota_reached"; - $sql = "INSERT INTO questionnaire_sample_quota_row (questionnaire_id,sample_import_id,lime_sgqa,value,comparison,completions,exclude_var,exclude_val,quota_reached,description) - SELECT questionnaire_id, $copy_sample_import_id, lime_sgqa,value,comparison,completions,exclude_var,exclude_val,0,description + $sql = "INSERT INTO questionnaire_sample_quota_row (questionnaire_id,sample_import_id,completions,quota_reached,description) + SELECT questionnaire_id, $copy_sample_import_id, completions,$b,description FROM questionnaire_sample_quota_row WHERE questionnaire_id = '$questionnaire_id' AND sample_import_id = '$sample_import_id'"; - $db->Execute($sql); + $db->Execute($sql); + + $nqsqr = $db->Insert_ID(); + + $sql = "INSERT INTO qsqr_sample (questionnaire_sample_quota_row_id,exclude_var,exclude_val,comparison,description) + SELECT $nqsqr, qs.exclude_var, qs.exclude_val, qs.comparison, qs.description + FROM qsqr_sample as qs, questionnaire_sample_quota_row as q + WHERE qs.questionnaire_sample_quota_row_id = q.questionnaire_sample_quota_row_id + AND q.questionnaire_id = '$questionnaire_id' + AND q.sample_import_id = '$sample_import_id'"; update_quotas($questionnaire_id); @@ -1568,22 +1604,7 @@ function copy_row_quota($questionnaire_id,$sample_import_id,$copy_sample_import_ */ function copy_row_quota_with_blocking($questionnaire_id,$sample_import_id,$copy_sample_import_id) { - global $db; - - $db->StartTrans(); - - //Set quota_reached to 0 always - - $sql = "INSERT INTO questionnaire_sample_quota_row (questionnaire_id,sample_import_id,lime_sgqa,value,comparison,completions,exclude_var,exclude_val,quota_reached,description) - SELECT questionnaire_id, $copy_sample_import_id, lime_sgqa,value,comparison,completions,exclude_var,exclude_val,quota_reached,description - FROM questionnaire_sample_quota_row - WHERE questionnaire_id = '$questionnaire_id' - AND sample_import_id = '$sample_import_id'"; - - $db->Execute($sql); - - - update_quotas($questionnaire_id); + copy_row_quota($questionnaire_id,$sample_import_id,$copy_sample_import_id,true); $db->CompleteTrans(); } @@ -1602,6 +1623,7 @@ function copy_row_quota_with_adjusting($questionnaire_id,$sample_import_id,$copy // Copy quotas (defalt Quexs function) copy_row_quota_with_blocking($questionnaire_id,$sample_import_id,$copy_sample_import_id); + /* $db->StartTrans(); // Select quotas from the old sample rows and calculate @@ -1642,7 +1664,8 @@ function copy_row_quota_with_adjusting($questionnaire_id,$sample_import_id,$copy } } - $db->CompleteTrans(); + $db->CompleteTrans(); + */ } @@ -1660,12 +1683,14 @@ function update_row_quota($questionnaire_id,$case_id = false) $db->StartTrans(); - $sql = "SELECT questionnaire_sample_quota_row_id,q.questionnaire_id,sample_import_id,lime_sgqa,value,comparison,completions,quota_reached,q.lime_sid,qsq.exclude_var,qsq.exclude_val,qsq.current_completions,qsq.priority,qsq.autoprioritise - FROM questionnaire_sample_quota_row as qsq, questionnaire as q + $sql = "SELECT questionnaire_sample_quota_row_id,q.questionnaire_id,sample_import_id,completions,quota_reached,q.lime_sid,qsq.current_completions,qsq.priority,qsq.autoprioritise + FROM questionnaire_sample_quota_row as qsq, questionnaire as q, qsqr_question as qq WHERE qsq.questionnaire_id = '$questionnaire_id' AND q.questionnaire_id = '$questionnaire_id' - AND qsq.quota_reached != '1' - AND qsq.lime_sgqa != -1"; + AND qsq.quota_reached != '1' + AND qq.questionnaire_sample_quota_row_id = qsq.questionnaire_sample_quota_row_id + AND qq.lime_sgqa != -1 + GROUP BY qsq.questionnaire_sample_quota_row_id"; $rs = $db->GetAll($sql); @@ -1676,7 +1701,25 @@ function update_row_quota($questionnaire_id,$case_id = false) //update all row quotas for this questionnaire foreach($rs as $r) - { + { + $lime_sid = $r['lime_sid']; + $qsqri = $r['questionnaire_sample_quota_row_id']; + + //all variables to exclude for this row quota + $sql2 = "SELECT exclude_val,exclude_var,comparison + FROM qsqr_sample + WHERE questionnaire_sample_quota_row_id = $qsqri"; + + $rev = $db->GetAll($sql2); + + //all variables to check in limesurvey for this row quota + $sql2 = "SELECT lime_sgqa,value,comparison + FROM qsqr_question + WHERE questionnaire_sample_quota_row_id = $qsqri"; + + $qev = $db->GetAll($sql2); + + //whether a completion was changed for this quota $updatequota = false; @@ -1684,10 +1727,45 @@ function update_row_quota($questionnaire_id,$case_id = false) //the quota criteria, and if so, increment the quota completions counter if ($case_id != false) { - if ($r['lime_sgqa'] == -2) - $match = limesurvey_quota_replicate_match($r['lime_sid'],$case_id,$r['exclude_val'],$r['exclude_var']); - else - $match = limesurvey_quota_match($r['lime_sgqa'],$r['lime_sid'],$case_id,$r['value'],$r['comparison']); + if ($r['lime_sgqa'] == -2) + { + //just determine if this case is linked to a matching sample record + + $sql2 = "SELECT count(*) as c + FROM " . LIME_PREFIX . "survey_$lime_sid as s + JOIN `case` as c ON (c.case_id = '$case_id') + JOIN `sample` as sam ON (c.sample_id = sam.sample_id) "; + + $x = 1; + foreach($rev as $ev) + { + $sql2 .= " JOIN sample_var as sv$x ON (sv$x.sample_id = sam.sample_id AND sv$x.var LIKE '{$ev['exclude_var']}' AND sv$x.val {$ev['comparison']} '{$ev['exclude_val']}') "; + $x++; + } + + $sql2 .= " WHERE s.token = c.token"; + + $match = $db->GetOne($sql2); + //$match = limesurvey_quota_replicate_match($r['lime_sid'],$case_id,$r['exclude_val'],$r['exclude_var']); + } + else + { + //determine if the case is linked to a matching limesurvey record + + $sql2 = "SELECT count(*) as c + FROM " . LIME_PREFIX . "survey_$lime_sid as s + JOIN `case` as c ON (c.case_id = '$case_id') + JOIN `sample` as sam ON (c.sample_id = sam.sample_id) + WHERE s.token = c.token + "; + + foreach($qev as $ev) + $sql2 .= " AND s.`{$ev['lime_sgqa']}` {$ev['comparison']} '{$ev['value']}' "; + + $match = $db->GetOne($sql2); + + //$match = limesurvey_quota_match($r['lime_sgqa'],$r['lime_sid'],$case_id,$r['value'],$r['comparison']); + } if ($match == 1) { @@ -1705,10 +1783,47 @@ function update_row_quota($questionnaire_id,$case_id = false) } else { - if ($r['lime_sgqa'] == -2) - $completions = limesurvey_quota_replicate_completions($r['lime_sid'],$r['questionnaire_id'],$r['sample_import_id'],$r['exclude_val'],$r['exclude_var']); - else - $completions = limesurvey_quota_completions($r['lime_sgqa'],$r['lime_sid'],$r['questionnaire_id'],$r['sample_import_id'],$r['value'],$r['comparison']); + if ($r['lime_sgqa'] == -2) + { + //find all completions from cases with matching sample records + + $sql2 = "SELECT count(*) as c + FROM " . LIME_PREFIX . "survey_$lime_sid as s + JOIN `case` as c ON (c.questionnaire_id = '$questionnaire_id') + JOIN `sample` as sam ON (c.sample_id = sam.sample_id AND sam.import_id = '$sample_import_id')"; + + $x = 1; + foreach($rev as $ev) + { + $sql2 .= " JOIN sample_var as sv$x ON (sv$x.sample_id = sam.sample_id AND sv$x.var LIKE '{$ev['exclude_var']}' AND sv$x.val {$ev['comparison']} '{$ev['exclude_val']}') "; + $x++; + } + + $sql2 .= " WHERE s.submitdate IS NOT NULL + AND s.token = c.token"; + + $completions = $db->GetOne($sql2); + + //$completions = limesurvey_quota_replicate_completions($r['lime_sid'],$r['questionnaire_id'],$r['sample_import_id'],$r['exclude_val'],$r['exclude_var']); + } + else + { + //find all completions from cases with matching limesurvey records + $sql2 = "SELECT count(*) as c + FROM " . LIME_PREFIX . "survey_$lime_sid as s + JOIN `case` as c ON (c.questionnaire_id = '$questionnaire_id') + JOIN `sample` as sam ON (c.sample_id = sam.sample_id AND sam.import_id = '$sample_import_id') + WHERE s.submitdate IS NOT NULL + AND s.token = c.token "; + + foreach($qev as $ev) + $sql2 .= " AND s.`{$ev['lime_sgqa']}` {$ev['comparison']} '{$ev['value']}' "; + + $completions = $db->GetOne($sql2); + + // $completions = limesurvey_quota_completions($r['lime_sgqa'],$r['lime_sid'],$r['questionnaire_id'],$r['sample_import_id'],$r['value'],$r['comparison']); + } + $updatequota = true; } @@ -1821,16 +1936,37 @@ function update_quota_priorities($questionnaire_id) $qsqri = $r['questionnaire_sample_quota_row_id']; $priority = $r['priority']; + $sql2 = "SELECT exclude_val,exclude_var,comparison + FROM qsqr_sample + WHERE questionnaire_sample_quota_row_id = $qsqri"; + + $rev = $db->GetAll($sql2); + + //find all cases that match this quota, and update it to the new priority - $sql = "UPDATE sample as s, sample_var as sv, questionnaire_sample_quota_row as qs, questionnaire_sample_exclude_priority as qsep + $sql = "UPDATE sample as s, questionnaire_sample_quota_row as qs, questionnaire_sample_exclude_priority as qsep "; + + //reduce sample by every item in the qsqr_sample table + $x = 1; + foreach ($rev as $ev) + { + $sql .= ", sample_var as sv$x"; + $x++; + } + + $sql .= " SET qsep.priority = '$priority' WHERE s.import_id = qs.sample_import_id AND qs.questionnaire_sample_quota_row_id = '$qsqri' - AND s.sample_id = sv.sample_id - AND sv.var = qs.exclude_var - AND qs.exclude_val LIKE sv.val AND qsep.questionnaire_id = qs.questionnaire_id - AND qsep.sample_id = s.sample_id"; + AND qsep.sample_id = s.sample_id "; + + $x = 1; + foreach ($rev as $ev) + { + $sql .= " AND sv$x.sample_id = s.sample_id AND sv$x.var LIKE '{$ev['exclude_var']}' AND sv$x.val {$ev['comparison']} '{$ev['exclude_val']}') "; + $x++; + } $db->Execute($sql); diff --git a/nocaseavailable.php b/nocaseavailable.php index ff8315de..01d14a2c 100644 --- a/nocaseavailable.php +++ b/nocaseavailable.php @@ -224,11 +224,12 @@ if (isset($rs) && !empty($rs)) } //quota row's full -$sql = "SELECT questionnaire_sample_quota_row_id,q.questionnaire_id,sample_import_id,lime_sgqa,value,comparison,completions,quota_reached,q.lime_sid - FROM questionnaire_sample_quota_row as qsq, questionnaire as q, operator_questionnaire as oq +$sql = "SELECT questionnaire_sample_quota_row_id,q.questionnaire_id,sample_import_id,qq.lime_sgqa,completions,quota_reached,q.lime_sid + FROM questionnaire_sample_quota_row as qsq, questionnaire as q, operator_questionnaire as oq, qsqr_question as qq WHERE oq.operator_id = '$operator_id' AND qsq.questionnaire_id = oq.questionnaire_id - AND q.questionnaire_id = oq.questionnaire_id"; + AND q.questionnaire_id = oq.questionnaire_id + AND qq.questionnaire_sample_quota_row_id = qsq.questionnaire_sample_quota_row_id"; $rs = $db->GetAll($sql); From 2226bb98cd356753d952c74a165240a771598bb1 Mon Sep 17 00:00:00 2001 From: Adam Zammit Date: Fri, 31 Jan 2014 15:35:58 +1100 Subject: [PATCH 3/9] updated database file to match new schema fixed bug when autoprioritising --- CHANGELOG | 9 ++++++++- database/quexs.sql | 11 +++-------- functions/functions.operator.php | 6 +++--- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 968c2b78..f02100cc 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,7 +17,8 @@ CREATE TABLE `qsqr_sample` ( `comparison` varchar(15) COLLATE utf8_unicode_ci NOT NULL, `description` text COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`qsqr_sample_id`), - KEY `questionnaire_sample_quota_row_id` (`questionnaire_sample_quota_row_id`) + KEY `questionnaire_sample_quota_row_id` (`questionnaire_sample_quota_row_id`), + KEY `exclude_var` (`exclude_var`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; @@ -29,6 +30,12 @@ INSERT INTO qsqr_sample (questionnaire_sample_quota_row_id,exclude_var,exclude_v SELECT questionnaire_sample_quota_row_id, exclude_var,exclude_val, 'LIKE' FROM questionnaire_sample_quota_row; +ALTER TABLE `questionnaire_sample_quota_row` + DROP `lime_sgqa`, + DROP `value`, + DROP `comparison`, + DROP `exclude_var`, + DROP `exclude_val`; queXS 1.10.0 - Changes since 1.9.2 diff --git a/database/quexs.sql b/database/quexs.sql index 5c82f807..abcade70 100644 --- a/database/quexs.sql +++ b/database/quexs.sql @@ -1391,7 +1391,8 @@ CREATE TABLE `qsqr_sample` ( `comparison` varchar(15) COLLATE utf8_unicode_ci NOT NULL, `description` text COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`qsqr_sample_id`), - KEY `questionnaire_sample_quota_row_id` (`questionnaire_sample_quota_row_id`) + KEY `questionnaire_sample_quota_row_id` (`questionnaire_sample_quota_row_id`), + KEY `exclude_var` (`exclude_var`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; @@ -1543,12 +1544,7 @@ CREATE TABLE `questionnaire_sample_quota_row` ( `questionnaire_sample_quota_row_id` bigint(20) NOT NULL auto_increment, `questionnaire_id` bigint(20) NOT NULL, `sample_import_id` bigint(20) NOT NULL, - `lime_sgqa` varchar(255) collate utf8_unicode_ci NOT NULL, - `value` varchar(2048) collate utf8_unicode_ci NOT NULL, - `comparison` varchar(15) collate utf8_unicode_ci NOT NULL default 'LIKE', `completions` int(11) NOT NULL, - `exclude_var` char(128) collate utf8_unicode_ci NOT NULL, - `exclude_val` varchar(256) collate utf8_unicode_ci NOT NULL, `quota_reached` tinyint(1) NOT NULL default '0', `current_completions` int(11) NOT NULL default '0', `description` text collate utf8_unicode_ci NOT NULL, @@ -1556,8 +1552,7 @@ CREATE TABLE `questionnaire_sample_quota_row` ( `autoprioritise` tinyint(1) NOT NULL default '0' COMMENT 'Should this row have it''s priority automatically adjusted to 100 - (completions %)', PRIMARY KEY (`questionnaire_sample_quota_row_id`), KEY `questionnaire_id` (`questionnaire_id`), - KEY `sample_import_id` (`sample_import_id`), - KEY `exclude_var` (`exclude_var`) + KEY `sample_import_id` (`sample_import_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- diff --git a/functions/functions.operator.php b/functions/functions.operator.php index 05692704..2b44dbcd 100644 --- a/functions/functions.operator.php +++ b/functions/functions.operator.php @@ -1683,7 +1683,7 @@ function update_row_quota($questionnaire_id,$case_id = false) $db->StartTrans(); - $sql = "SELECT questionnaire_sample_quota_row_id,q.questionnaire_id,sample_import_id,completions,quota_reached,q.lime_sid,qsq.current_completions,qsq.priority,qsq.autoprioritise + $sql = "SELECT qsq.questionnaire_sample_quota_row_id,q.questionnaire_id,sample_import_id,completions,quota_reached,q.lime_sid,qsq.current_completions,qsq.priority,qsq.autoprioritise,qq.lime_sgqa FROM questionnaire_sample_quota_row as qsq, questionnaire as q, qsqr_question as qq WHERE qsq.questionnaire_id = '$questionnaire_id' AND q.questionnaire_id = '$questionnaire_id' @@ -1703,6 +1703,7 @@ function update_row_quota($questionnaire_id,$case_id = false) foreach($rs as $r) { $lime_sid = $r['lime_sid']; + $sample_import_id = $r['sample_import_id']; $qsqri = $r['questionnaire_sample_quota_row_id']; //all variables to exclude for this row quota @@ -1719,7 +1720,6 @@ function update_row_quota($questionnaire_id,$case_id = false) $qev = $db->GetAll($sql2); - //whether a completion was changed for this quota $updatequota = false; @@ -1964,7 +1964,7 @@ function update_quota_priorities($questionnaire_id) $x = 1; foreach ($rev as $ev) { - $sql .= " AND sv$x.sample_id = s.sample_id AND sv$x.var LIKE '{$ev['exclude_var']}' AND sv$x.val {$ev['comparison']} '{$ev['exclude_val']}') "; + $sql .= " AND sv$x.sample_id = s.sample_id AND sv$x.var LIKE '{$ev['exclude_var']}' AND sv$x.val {$ev['comparison']} '{$ev['exclude_val']}' "; $x++; } From 03c34c12ce49cc01f2caf3b28e3a161c9197cf94 Mon Sep 17 00:00:00 2001 From: Adam Zammit Date: Wed, 19 Feb 2014 15:02:56 +1100 Subject: [PATCH 4/9] Handle editing/deleting of quota restrictions --- admin/quotarow.php | 127 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 108 insertions(+), 19 deletions(-) diff --git a/admin/quotarow.php b/admin/quotarow.php index ef066e1f..5fc7e917 100755 --- a/admin/quotarow.php +++ b/admin/quotarow.php @@ -69,6 +69,26 @@ include("../functions/functions.operator.php"); global $db; + +if (isset($_GET['delete'])) +{ + if (isset($_GET['qsqrqi'])) + { + $qsqrqi = bigintval($_GET['qsqrqi']); + $sql = "DELETE FROM qsqr_question + WHERE qsqr_question_id = $qsqrqi"; + $db->Execute($sql); + } + if (isset($_GET['qsqrsi'])) + { + $qsqrsi = bigintval($_GET['qsqrsi']); + $sql = "DELETE FROM qsqr_sample + WHERE qsqr_sample_id = $qsqrsi"; + $db->Execute($sql); + } +} + + if (isset($_POST['add_quota'])) { //need to add quota @@ -89,6 +109,30 @@ if (isset($_POST['add_quota'])) //update_quotas($questionnaire_id); } +if (isset($_POST['edit_quota'])) +{ + $completions = intval($_POST['completions']); + $autoprioritise = 0; + if (isset($_POST['autoprioritise'])) $autoprioritise = 1; + $priority = intval($_POST['priority']); + $description = $db->quote($_POST['description']); + $qsqri = bigintval($_POST['qsqri']); + + $sql = "UPDATE questionnaire_sample_quota_row + SET completions = $completions, + autoprioritise = $autoprioritise, + priority = $priority, + description = $description + WHERE questionnaire_sample_quota_row_id = $qsqri"; + + $db->Execute($sql); + + $_GET['qsqri'] = $qsqri; + $_GET['edit'] = "edit"; + //Make sure to calculate on the spot + //update_quotas($questionnaire_id); +} + $qsqri = false; $qsqrid = false; @@ -96,7 +140,7 @@ if (isset($_GET['qsqri']) & isset($_GET['edit'])) { $qsqri = bigintval($_GET['qsqri']); - $sql = "SELECT questionnaire_id,sample_import_id,description + $sql = "SELECT questionnaire_id,sample_import_id,description,autoprioritise,priority,completions FROM questionnaire_sample_quota_row WHERE questionnaire_sample_quota_row_id = $qsqri"; @@ -105,6 +149,35 @@ if (isset($_GET['qsqri']) & isset($_GET['edit'])) $_GET['questionnaire_id'] = $rs['questionnaire_id']; $_GET['sample_import_id'] = $rs['sample_import_id']; $qsqrid = $rs['description']; + $qsqrich = ""; + if ($rs['autoprioritise'] == 1) + $qsqrich = "checked=\"checked\""; + $qsqric = $rs['completions']; + $qsqrip = $rs['priority']; + + if (isset($_POST['adds'])) + { + $comparison = $db->qstr($_POST['comparisons']); + $exvar = $db->qstr(substr($_POST['sample_var'],12,strpos($_POST['sample_var'],'&')-12)); + $exval = $db->qstr($_POST['exclude_val']); + //add ssample + $sql = "INSERT INTO qsqr_sample (questionnaire_sample_quota_row_id,exclude_var,exclude_val,comparison) + VALUES ($qsqri,$exvar,$exval,$comparison)"; + + $db->Execute($sql); + } + + if (isset($_POST['addq'])) + { + $comparison = $db->qstr($_POST['comparison']); + $value = $db->qstr($_POST['value']); + $sgqa = $db->qstr(substr($_POST['sgqa'],6,strpos($_POST['sgqa'],'&')-6)); + //add ssample + $sql = "INSERT INTO qsqr_question (questionnaire_sample_quota_row_id,lime_sgqa,value,comparison) + VALUES ($qsqri,$sgqa,$value,$comparison)"; + + $db->Execute($sql); + } } $questionnaire_id = false; @@ -140,14 +213,13 @@ if ($questionnaire_id != false) print "

" . T_("Quota") . ": $qsqrid

"; print "

" . T_("Go back") . "

"; - print "

" . T_("Edit row quota") . "

"; ?>
" method="post">

-
-
-
-
+
+
+ />
+
"/>

@@ -155,7 +227,7 @@ if ($questionnaire_id != false) //display questionnaire references $sql = "SELECT qsqr_question_id,lime_sgqa,value,comparison,description, - CONCAT('" . TQ_("Delete") . "') as qdelete + CONCAT('" . TQ_("Delete") . "') as qdelete FROM qsqr_question WHERE questionnaire_sample_quota_row_id = $qsqri"; @@ -164,7 +236,7 @@ if ($questionnaire_id != false) if (empty($rs)) { - print "

" . T_("All completed responses will be counted") . "

"; + print "

" . T_("All completed responses that match the sample criteria below will be counted towards the quota") . "

"; } else { @@ -180,8 +252,12 @@ if ($questionnaire_id != false) $lime_sid = $db->GetOne($sql); + $ssgqa = "''"; + if (isset($_GET['sgqa'])) + $ssgqa = $db->qstr($_GET['sgqa']); + //select question - $sql = "SELECT CONCAT( lq.sid, 'X', lq.gid, 'X', CASE WHEN lq.parent_qid = 0 THEN lq.qid ELSE CONCAT(lq.parent_qid, lq.title) END) as value, CASE WHEN lq.parent_qid = 0 THEN lq.question ELSE CONCAT(lq2.question, ': ', lq.question) END as description, '' AS selected + $sql = "SELECT CONCAT( lq.sid, 'X', lq.gid, 'X', CASE WHEN lq.parent_qid = 0 THEN lq.qid ELSE CONCAT(lq.parent_qid, lq.title) END) as value, CASE WHEN lq.parent_qid = 0 THEN lq.question ELSE CONCAT(lq2.question, ': ', lq.question) END as description, CASE WHEN $ssgqa LIKE CONCAT( lq.sid, 'X', lq.gid, 'X', CASE WHEN lq.parent_qid = 0 THEN lq.qid ELSE CONCAT(lq.parent_qid, lq.title) END) THEN 'selected=\'selected\'' ELSE '' END AS selected FROM `" . LIME_PREFIX . "questions` AS lq LEFT JOIN `" . LIME_PREFIX . "questions` AS lq2 ON ( lq2.qid = lq.parent_qid ) JOIN `" . LIME_PREFIX . "groups` as g ON (g.gid = lq.gid) @@ -192,20 +268,22 @@ if ($questionnaire_id != false) if (!empty($rs)) { + print "
"; print "

" . T_("Add restriction based on answered questions") . "

"; print ""; - display_chooser($rs,"sgqa","sgqa",false,"qsqri=$qsqri",false,false); + display_chooser($rs,"sgqa","sgqa",false,"edit=edit&qsqri=$qsqri",true,false); ?>


"/> +
" . TQ_("Delete") . "') as sdelete + CONCAT('" . TQ_("Delete") . "') as sdelete FROM qsqr_sample WHERE questionnaire_sample_quota_row_id = $qsqri"; @@ -213,17 +291,21 @@ if ($questionnaire_id != false) if (empty($rs)) { - print "

" . T_("All sample records will be counted") . "

"; + print "

" . T_("All sample records will be excluded") . "

"; } else { - print "

" . T_("Only completed responses that have the following sample details will be counted") . "

"; + print "

" . T_("Completed responses that have the following sample details will be counted towards the quota and excluded when the quota is reached") . "

"; xhtml_table($rs,array('exclude_var','comparison','exclude_val','sdelete'),array(T_("Sample record"),T_("Comparison"),T_("Value"),T_("Delete"))); } + $ssample_var = "''"; + if (isset($_GET['sample_var'])) + $ssample_var = $db->qstr($_GET['sample_var']); + //add sample references (records from sample to exclude when quota reached) - $sql = "SELECT sv.var as value, sv.var as description, '' AS selected + $sql = "SELECT sv.var as value, sv.var as description, CASE WHEN sv.var LIKE $ssample_var THEN 'selected=\'selected\'' ELSE '' END AS selected FROM sample_var AS sv, sample AS s WHERE s.import_id = $sample_import_id AND s.sample_id = sv.sample_id @@ -233,25 +315,30 @@ if ($questionnaire_id != false) if (!empty($rs)) { + if ($ssample_var == "''") + $ssample_var = "'" . $rs[0]['value']. "'"; + print "

" . T_("Add restriction based on sample records") . "

"; + print "
"; print ""; - display_chooser($db->GetAll($sql),"sample_var","sample_var",false,"qsqri=$qsqri",false,false); + display_chooser($rs,"sample_var","sample_var",false,"edit=edit&qsqri=$qsqri",true,false); ?>

- + GetAll($sql),"exclude_val","exclude_val",false,false,false,false); flush(); ?>
"/> +
', qsq.description, '') as qedit, CONCAT('') as qselect, - qsq.completions,qsq.quota_reached,qsq.current_completions + qsq.completions,qsq.quota_reached,qsq.current_completions, + CASE WHEN qsq.autoprioritise = 1 THEN '" . TQ_("Yes") . "' ELSE '" . TQ_("No") . "' END AS ap, qsq.priority, + CASE WHEN qsq.quota_reached = 1 THEN '" . TQ_("closed") . "' ELSE '" . TQ_("open") . "' END AS status FROM questionnaire_sample_quota_row as qsq, questionnaire as q WHERE qsq.questionnaire_id = '$questionnaire_id' AND qsq.sample_import_id = '$sample_import_id' @@ -280,7 +369,7 @@ if ($questionnaire_id != false) } else { - xhtml_table($r,array('qedit','completions','current_completions','qselect'),array(T_("Description"),T_("Quota"),T_("Completions"),T_("Select"))); + xhtml_table($r,array('qedit','completions','current_completions','status','priority','ap','qselect'),array(T_("Description"),T_("Quota"),T_("Completions"),T_("Status"),T_("Priority"),T_("Auto prioritise"),T_("Select"))); print ""; print ""; From ed6b89f1d9bfae4a81e3b928070219447c94deb2 Mon Sep 17 00:00:00 2001 From: Adam Zammit Date: Wed, 19 Feb 2014 15:06:21 +1100 Subject: [PATCH 5/9] Don't rely on qsqr_question table as not necessary --- nocaseavailable.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/nocaseavailable.php b/nocaseavailable.php index 01d14a2c..8f574094 100644 --- a/nocaseavailable.php +++ b/nocaseavailable.php @@ -224,12 +224,10 @@ if (isset($rs) && !empty($rs)) } //quota row's full -$sql = "SELECT questionnaire_sample_quota_row_id,q.questionnaire_id,sample_import_id,qq.lime_sgqa,completions,quota_reached,q.lime_sid - FROM questionnaire_sample_quota_row as qsq, questionnaire as q, operator_questionnaire as oq, qsqr_question as qq +$sql = "SELECT qsq.questionnaire_sample_quota_row_id,qsq.quota_reached,qsq.description + FROM questionnaire_sample_quota_row as qsq, operator_questionnaire as oq WHERE oq.operator_id = '$operator_id' - AND qsq.questionnaire_id = oq.questionnaire_id - AND q.questionnaire_id = oq.questionnaire_id - AND qq.questionnaire_sample_quota_row_id = qsq.questionnaire_sample_quota_row_id"; + AND qsq.questionnaire_id = oq.questionnaire_id"; $rs = $db->GetAll($sql); @@ -239,7 +237,7 @@ if (isset($rs) && !empty($rs)) { if ($r['quota_reached'] == 1) { - print "

" . T_("POSSIBLE ERROR: Row quota reached for this question") . " - " . $r['lime_sgqa']; + print "

" . T_("POSSIBLE ERROR: Row quota reached for this quota") . " - " . $r['description']; } } } From 942464768e8638c4af882d0459da6023f7e5b65c Mon Sep 17 00:00:00 2001 From: Adam Zammit Date: Wed, 19 Feb 2014 15:58:34 +1100 Subject: [PATCH 6/9] Allow for single row quotas to be updated on editing --- admin/quotareport.php | 24 +- admin/quotarow.php | 23 +- functions/functions.operator.php | 369 ++++++++++++++++--------------- 3 files changed, 218 insertions(+), 198 deletions(-) diff --git a/admin/quotareport.php b/admin/quotareport.php index 6f057df4..d4318c87 100644 --- a/admin/quotareport.php +++ b/admin/quotareport.php @@ -178,13 +178,12 @@ if ($questionnaire_id) $report[] = array("strata" => T_("Total sample"), "quota" => $drawn + $remain, "sample" => $drawn + $remain, "sampleused" => $drawn, "sampleremain" => $remain, "completions" => $completions, "perc" => ROUND(($completions / ($drawn + $remain)) * 100,2)); //a. (Standard quota) Monitor outcomes of questions in completed questionnaires, and exclude selected sample records when completion limit is reached - //b. (Replicate quota) Exclude selected sample records (where lime_sgqa == -1) - $sql = "SELECT qsq.questionnaire_sample_quota_row_id,qsqr_question.lime_sgqa,completions,quota_reached,lime_sid,qsq.description,current_completions, priority, autoprioritise - FROM questionnaire_sample_quota_row as qsq, questionnaire as q, qsqr_question - WHERE qsq.questionnaire_id = '$questionnaire_id' + //b. (Replicate quota) Exclude selected sample records (where no qsqr_question rows) + $sql = "SELECT qsq.questionnaire_sample_quota_row_id,completions,quota_reached,lime_sid,qsq.description,current_completions, priority, autoprioritise + FROM questionnaire_sample_quota_row as qsq, questionnaire as q + WHERE qsq.questionnaire_id = '$questionnaire_id' AND qsq.sample_import_id = '$sample_import_id' - AND q.questionnaire_id = '$questionnaire_id' - AND qsqr_question.questionnaire_sample_quota_row_id = qsq.questionnaire_sample_quota_row_id"; + AND q.questionnaire_id = '$questionnaire_id'"; $r = $db->GetAll($sql); @@ -198,15 +197,8 @@ if ($questionnaire_id) $qsqr = $v['questionnaire_sample_quota_row_id']; - if ($v['lime_sgqa'] == -1) - { - $v['completions'] = ""; - $perc = ""; - } - else - { - $perc = ($v['completions'] <= 0 ? 0 : ROUND(($completions / ($v['completions'])) * 100,2)); - } + $perc = ($v['completions'] <= 0 ? 0 : ROUND(($completions / ($v['completions'])) * 100,2)); + //We need to calc Sample size, Sample drawn, Sample remain $sql = "SELECT (c.sample_id is not null) as type, count(*) as count @@ -242,7 +234,7 @@ if ($questionnaire_id) if ($r['type'] == 0) $remain = $r['count']; } - if ($completions < $v['completions'] || $v['lime_sgqa'] == -1) //if completions less than the quota, allow for closing/opening + if ($completions < $v['completions']) //if completions less than the quota, allow for closing/opening { if ($v['quota_reached'] == 1) $status = "" . T_("closed") . ""; diff --git a/admin/quotarow.php b/admin/quotarow.php index 5fc7e917..61428855 100755 --- a/admin/quotarow.php +++ b/admin/quotarow.php @@ -72,12 +72,17 @@ global $db; if (isset($_GET['delete'])) { + $qsqri = bigintval($_GET['qsqri']); + if (isset($_GET['qsqrqi'])) { $qsqrqi = bigintval($_GET['qsqrqi']); $sql = "DELETE FROM qsqr_question WHERE qsqr_question_id = $qsqrqi"; $db->Execute($sql); + + //Make sure to calculate on the spot + update_single_row_quota($qsqri); } if (isset($_GET['qsqrsi'])) { @@ -85,6 +90,9 @@ if (isset($_GET['delete'])) $sql = "DELETE FROM qsqr_sample WHERE qsqr_sample_id = $qsqrsi"; $db->Execute($sql); + + //Make sure to calculate on the spot + update_single_row_quota($qsqri); } } @@ -103,10 +111,12 @@ if (isset($_POST['add_quota'])) $sql = "INSERT INTO questionnaire_sample_quota_row(questionnaire_id, sample_import_id, completions, description, priority, autoprioritise) VALUES ($questionnaire_id, $sample_import_id, $completions, $description, $priority, $autoprioritise)"; - $db->Execute($sql); + $db->Execute($sql); + + $qq = $db->Insert_ID(); //Make sure to calculate on the spot - //update_quotas($questionnaire_id); + update_single_row_quota($qq); } if (isset($_POST['edit_quota'])) @@ -129,8 +139,9 @@ if (isset($_POST['edit_quota'])) $_GET['qsqri'] = $qsqri; $_GET['edit'] = "edit"; + //Make sure to calculate on the spot - //update_quotas($questionnaire_id); + update_single_row_quota($qsqri); } @@ -165,6 +176,9 @@ if (isset($_GET['qsqri']) & isset($_GET['edit'])) VALUES ($qsqri,$exvar,$exval,$comparison)"; $db->Execute($sql); + + //Make sure to calculate on the spot + update_single_row_quota($qsqri); } if (isset($_POST['addq'])) @@ -177,6 +191,9 @@ if (isset($_GET['qsqri']) & isset($_GET['edit'])) VALUES ($qsqri,$sgqa,$value,$comparison)"; $db->Execute($sql); + + //Make sure to calculate on the spot + update_single_row_quota($qsqri); } } diff --git a/functions/functions.operator.php b/functions/functions.operator.php index 2b44dbcd..e0c8a5da 100644 --- a/functions/functions.operator.php +++ b/functions/functions.operator.php @@ -1668,6 +1668,184 @@ function copy_row_quota_with_adjusting($questionnaire_id,$sample_import_id,$copy */ } +/** + * Update a single row quota + * + * @param int $qsqri The quota row id + * @param int|bool $case_id The case id if known to limit the scope of the search + * @return bool If priorities need to be updated or not + */ +function update_single_row_quota($qsqri,$case_id = false) +{ + global $db; + + $sql = "SELECT q.lime_sid, qs.questionnaire_id, qs.sample_import_id, qs.completions, qs.autoprioritise + FROM questionnaire as q, questionnaire_sample_quota_row as qs + WHERE q.questionnaire_id = qs.questionnaire_id + AND qs.questionnaire_sample_quota_row_id = $qsqri"; + + $rs = $db->GetRow($sql); + + $lime_sid = $rs['lime_sid']; + $questionnaire_id = $rs['questionnaire_id']; + $sample_import_id = $rs['sample_import_id']; + $target_completions = $rs['completions']; + $autoprioritise = $rs['autoprioritise']; + + //all variables to exclude for this row quota + $sql2 = "SELECT exclude_val,exclude_var,comparison + FROM qsqr_sample + WHERE questionnaire_sample_quota_row_id = $qsqri"; + + $rev = $db->GetAll($sql2); + + //all variables to check in limesurvey for this row quota + $sql2 = "SELECT lime_sgqa,value,comparison + FROM qsqr_question + WHERE questionnaire_sample_quota_row_id = $qsqri"; + + $qev = $db->GetAll($sql2); + + //whether a completion was changed for this quota + $updatequota = false; + //whether priorites need to be updated + $update = false; + //default completions at 0 + $completions = 0; + + //if a case_Id is specified, we can just check if this case matches + //the quota criteria, and if so, increment the quota completions counter + if ($case_id != false) + { + if (empty($qev)) + { + //just determine if this case is linked to a matching sample record + $sql2 = "SELECT count(*) as c + FROM " . LIME_PREFIX . "survey_$lime_sid as s + JOIN `case` as c ON (c.case_id = '$case_id') + JOIN `sample` as sam ON (c.sample_id = sam.sample_id) "; + + $x = 1; + foreach($rev as $ev) + { + $sql2 .= " JOIN sample_var as sv$x ON (sv$x.sample_id = sam.sample_id AND sv$x.var LIKE '{$ev['exclude_var']}' AND sv$x.val {$ev['comparison']} '{$ev['exclude_val']}') "; + $x++; + } + + $sql2 .= " WHERE s.token = c.token"; + + $match = $db->GetOne($sql2); + } + else + { + //determine if the case is linked to a matching limesurvey record + $sql2 = "SELECT count(*) as c + FROM " . LIME_PREFIX . "survey_$lime_sid as s + JOIN `case` as c ON (c.case_id = '$case_id') + JOIN `sample` as sam ON (c.sample_id = sam.sample_id) + WHERE s.token = c.token + "; + + foreach($qev as $ev) + $sql2 .= " AND s.`{$ev['lime_sgqa']}` {$ev['comparison']} '{$ev['value']}' "; + + $match = $db->GetOne($sql2); + } + + if ($match == 1) + { + //increment completions + $sql = "SELECT (current_completions + 1) as c + FROM questionnaire_sample_quota_row + WHERE questionnaire_sample_quota_row_id = '$qsqri'"; + $cc = $db->GetRow($sql); + + $completions = $cc['c']; + + $updatequota = true; + } + } + else + { + if (empty($qev)) + { + //find all completions from cases with matching sample records + + $sql2 = "SELECT count(*) as c + FROM " . LIME_PREFIX . "survey_$lime_sid as s + JOIN `case` as c ON (c.questionnaire_id = '$questionnaire_id') + JOIN `sample` as sam ON (c.sample_id = sam.sample_id AND sam.import_id = '$sample_import_id')"; + + $x = 1; + foreach($rev as $ev) + { + $sql2 .= " JOIN sample_var as sv$x ON (sv$x.sample_id = sam.sample_id AND sv$x.var LIKE '{$ev['exclude_var']}' AND sv$x.val {$ev['comparison']} '{$ev['exclude_val']}') "; + $x++; + } + + $sql2 .= " WHERE s.submitdate IS NOT NULL + AND s.token = c.token"; + + $completions = $db->GetOne($sql2); + } + else + { + //find all completions from cases with matching limesurvey records + $sql2 = "SELECT count(*) as c + FROM " . LIME_PREFIX . "survey_$lime_sid as s + JOIN `case` as c ON (c.questionnaire_id = '$questionnaire_id') + JOIN `sample` as sam ON (c.sample_id = sam.sample_id AND sam.import_id = '$sample_import_id') + WHERE s.submitdate IS NOT NULL + AND s.token = c.token "; + + foreach($qev as $ev) + $sql2 .= " AND s.`{$ev['lime_sgqa']}` {$ev['comparison']} '{$ev['value']}' "; + + $completions = $db->GetOne($sql2); + } + + $updatequota = true; + } + + if ($updatequota) + { + if ($completions >= $target_completions) + { + //set row quota to reached + $sql = "UPDATE questionnaire_sample_quota_row + SET quota_reached = '1', current_completions = '$completions' + WHERE questionnaire_sample_quota_row_id = '$qsqri'"; + + $db->Execute($sql); + + close_row_quota($qsqri,false); //don't update priorires just yet + $update = true; + } + else + { + $sql = "UPDATE questionnaire_sample_quota_row + SET current_completions = '$completions' "; + + //If autopriority is set update it here + if ($autoprioritise == 1) + { + //priority is 100 - the percentage of completions + $pr = 100 - round(100 * ($completions / $target_completions)); + $sql .= ", priority = '$pr' "; + + //need to update quotas now + $update = true; + } + + $sql .= " WHERE questionnaire_sample_quota_row_id = '$qsqri'"; + + $db->Execute($sql); + + } + } + return $update; +} + /** * Update the row quota table @@ -1683,197 +1861,30 @@ function update_row_quota($questionnaire_id,$case_id = false) $db->StartTrans(); - $sql = "SELECT qsq.questionnaire_sample_quota_row_id,q.questionnaire_id,sample_import_id,completions,quota_reached,q.lime_sid,qsq.current_completions,qsq.priority,qsq.autoprioritise,qq.lime_sgqa - FROM questionnaire_sample_quota_row as qsq, questionnaire as q, qsqr_question as qq + $sql = "SELECT qsq.questionnaire_sample_quota_row_id + FROM questionnaire_sample_quota_row as qsq WHERE qsq.questionnaire_id = '$questionnaire_id' - AND q.questionnaire_id = '$questionnaire_id' AND qsq.quota_reached != '1' - AND qq.questionnaire_sample_quota_row_id = qsq.questionnaire_sample_quota_row_id - AND qq.lime_sgqa != -1 GROUP BY qsq.questionnaire_sample_quota_row_id"; $rs = $db->GetAll($sql); - if (isset($rs) && !empty($rs)) - { - //include limesurvey functions - include_once(dirname(__FILE__).'/functions.limesurvey.php'); - - //update all row quotas for this questionnaire - foreach($rs as $r) + if (isset($rs) && !empty($rs)) + { + foreach ($rs as $r) { - $lime_sid = $r['lime_sid']; - $sample_import_id = $r['sample_import_id']; - $qsqri = $r['questionnaire_sample_quota_row_id']; + $tmp = update_single_row_quota($r['questionnaire_sample_quota_row_id'],$case_id); + if ($tmp) + $update = true; + } + } - //all variables to exclude for this row quota - $sql2 = "SELECT exclude_val,exclude_var,comparison - FROM qsqr_sample - WHERE questionnaire_sample_quota_row_id = $qsqri"; - - $rev = $db->GetAll($sql2); - - //all variables to check in limesurvey for this row quota - $sql2 = "SELECT lime_sgqa,value,comparison - FROM qsqr_question - WHERE questionnaire_sample_quota_row_id = $qsqri"; - - $qev = $db->GetAll($sql2); - - //whether a completion was changed for this quota - $updatequota = false; - - //if a case_Id is specified, we can just check if this case matches - //the quota criteria, and if so, increment the quota completions counter - if ($case_id != false) - { - if ($r['lime_sgqa'] == -2) - { - //just determine if this case is linked to a matching sample record - - $sql2 = "SELECT count(*) as c - FROM " . LIME_PREFIX . "survey_$lime_sid as s - JOIN `case` as c ON (c.case_id = '$case_id') - JOIN `sample` as sam ON (c.sample_id = sam.sample_id) "; - - $x = 1; - foreach($rev as $ev) - { - $sql2 .= " JOIN sample_var as sv$x ON (sv$x.sample_id = sam.sample_id AND sv$x.var LIKE '{$ev['exclude_var']}' AND sv$x.val {$ev['comparison']} '{$ev['exclude_val']}') "; - $x++; - } - - $sql2 .= " WHERE s.token = c.token"; - - $match = $db->GetOne($sql2); - //$match = limesurvey_quota_replicate_match($r['lime_sid'],$case_id,$r['exclude_val'],$r['exclude_var']); - } - else - { - //determine if the case is linked to a matching limesurvey record - - $sql2 = "SELECT count(*) as c - FROM " . LIME_PREFIX . "survey_$lime_sid as s - JOIN `case` as c ON (c.case_id = '$case_id') - JOIN `sample` as sam ON (c.sample_id = sam.sample_id) - WHERE s.token = c.token - "; - - foreach($qev as $ev) - $sql2 .= " AND s.`{$ev['lime_sgqa']}` {$ev['comparison']} '{$ev['value']}' "; - - $match = $db->GetOne($sql2); - - //$match = limesurvey_quota_match($r['lime_sgqa'],$r['lime_sid'],$case_id,$r['value'],$r['comparison']); - } - - if ($match == 1) - { - //increment completions - $sql = "SELECT (current_completions + 1) as c - FROM questionnaire_sample_quota_row - WHERE questionnaire_sample_quota_row_id = {$r['questionnaire_sample_quota_row_id']}"; - $cc = $db->GetRow($sql); - - $completions = $cc['c']; - - $updatequota = true; - } - - } - else - { - if ($r['lime_sgqa'] == -2) - { - //find all completions from cases with matching sample records - - $sql2 = "SELECT count(*) as c - FROM " . LIME_PREFIX . "survey_$lime_sid as s - JOIN `case` as c ON (c.questionnaire_id = '$questionnaire_id') - JOIN `sample` as sam ON (c.sample_id = sam.sample_id AND sam.import_id = '$sample_import_id')"; - - $x = 1; - foreach($rev as $ev) - { - $sql2 .= " JOIN sample_var as sv$x ON (sv$x.sample_id = sam.sample_id AND sv$x.var LIKE '{$ev['exclude_var']}' AND sv$x.val {$ev['comparison']} '{$ev['exclude_val']}') "; - $x++; - } - - $sql2 .= " WHERE s.submitdate IS NOT NULL - AND s.token = c.token"; - - $completions = $db->GetOne($sql2); - - //$completions = limesurvey_quota_replicate_completions($r['lime_sid'],$r['questionnaire_id'],$r['sample_import_id'],$r['exclude_val'],$r['exclude_var']); - } - else - { - //find all completions from cases with matching limesurvey records - $sql2 = "SELECT count(*) as c - FROM " . LIME_PREFIX . "survey_$lime_sid as s - JOIN `case` as c ON (c.questionnaire_id = '$questionnaire_id') - JOIN `sample` as sam ON (c.sample_id = sam.sample_id AND sam.import_id = '$sample_import_id') - WHERE s.submitdate IS NOT NULL - AND s.token = c.token "; - - foreach($qev as $ev) - $sql2 .= " AND s.`{$ev['lime_sgqa']}` {$ev['comparison']} '{$ev['value']}' "; - - $completions = $db->GetOne($sql2); - - // $completions = limesurvey_quota_completions($r['lime_sgqa'],$r['lime_sid'],$r['questionnaire_id'],$r['sample_import_id'],$r['value'],$r['comparison']); - } - - $updatequota = true; - } - - if ($updatequota) - { - if ($completions >= $r['completions']) - { - //set row quota to reached - $sql = "UPDATE questionnaire_sample_quota_row - SET quota_reached = '1', current_completions = '$completions' - WHERE questionnaire_sample_quota_row_id = {$r['questionnaire_sample_quota_row_id']}"; - - $db->Execute($sql); - - close_row_quota($r['questionnaire_sample_quota_row_id'],false); //don't update priorires just yet - $update = true; - } - else - { - $sql = "UPDATE questionnaire_sample_quota_row - SET current_completions = '$completions' "; - - //If autopriority is set update it here - if ($r['autoprioritise'] == 1) - { - //priority is 100 - the percentage of completions - $pr = 100 - round(100 * ($completions / $r['completions'])); - $sql .= ", priority = '$pr' "; - - //need to update quotas now - $update = true; - } - - $sql .= " WHERE questionnaire_sample_quota_row_id = {$r['questionnaire_sample_quota_row_id']}"; - - $db->Execute($sql); - - } - - - } - - } - if ($update) update_quota_priorities($questionnaire_id); - } + if ($update) + update_quota_priorities($questionnaire_id); $db->CompleteTrans(); return false; - } /** From fbd449c227e9874a564a543d41657814316ba9b5 Mon Sep 17 00:00:00 2001 From: Adam Zammit Date: Thu, 13 Mar 2014 15:10:20 +1100 Subject: [PATCH 7/9] Updated changelog --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 82a2d31e..8811347b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -25,6 +25,7 @@ CREATE TABLE `qsqr_sample` ( INSERT INTO qsqr_question (questionnaire_sample_quota_row_id,lime_sgqa,value,comparison) SELECT questionnaire_sample_quota_row_id, lime_sgqa, value, comparison FROM questionnaire_sample_quota_row; +WHERE lime_sgqa != -1 AND lime_sgqa != -2 INSERT INTO qsqr_sample (questionnaire_sample_quota_row_id,exclude_var,exclude_val,comparison) SELECT questionnaire_sample_quota_row_id, exclude_var,exclude_val, 'LIKE' From 7ef3e2b3d268b2aebe33f6a452b9f7d647988c90 Mon Sep 17 00:00:00 2001 From: Adam Zammit Date: Fri, 14 Mar 2014 15:47:07 +1100 Subject: [PATCH 8/9] allow for deleting, exporting to CSV and importing from CSV of row quotas --- admin/quotarow.php | 152 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/admin/quotarow.php b/admin/quotarow.php index 61428855..552eb7b4 100755 --- a/admin/quotarow.php +++ b/admin/quotarow.php @@ -70,6 +70,85 @@ include("../functions/functions.operator.php"); global $db; +if (isset($_POST['submitdelete'])) +{ + foreach($_POST as $key => $val) + { + if (substr($key,0,7) == "select_") + { + $tmp = bigintval(substr($key,7)); + open_row_quota($tmp); + } + } +} + +if (isset($_POST['submitexport'])) +{ + $csv = array(); + foreach($_POST as $key => $val) + { + if (substr($key,0,7) == "select_") + { + $tmp = bigintval(substr($key,7)); + + $sql = "SELECT description,completions,autoprioritise + FROM questionnaire_sample_quota_row + WHERE questionnaire_sample_quota_row_id = $tmp"; + + $rs = $db->GetRow($sql); + + $sql = "SELECT lime_sgqa,comparison,value + FROM qsqr_question + WHERE questionnaire_sample_quota_row_id = $tmp"; + + $q2 = $db->GetAll($sql); + + $sql = "SELECT exclude_var as samplerecord,comparison,exclude_val as value + FROM qsqr_sample + WHERE questionnaire_sample_quota_row_id = $tmp"; + + $q3 = $db->GetAll($sql); + + $ta = array($rs['description'],$rs['completions'],$rs['autoprioritise']); + + //just search where col 1 looks like 333X2X2 and assume it is a question + + foreach($q2 as $qr) + foreach($qr as $qe => $val) + $ta[] = $val; + + foreach($q3 as $qr) + foreach($qr as $qe => $val) + $ta[] = $val; + + $csv[] = $ta; + } + } + if (!empty($csv)) + { + $fn = T_("Quota") .".csv"; + + header("Content-Type: text/csv"); + header("Content-Disposition: attachment; filename=$fn"); + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + Header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); + header("Pragma: no-cache"); // HTTP/1.0 + + foreach($csv as $cr) + { + for ($i = 0; $i < count($cr); $i++) + { + echo str_replace(","," ",$cr[$i]); + if ($i < (count($cr) - 1)) + echo ","; + } + echo "\n"; + } + die(); + } +} + if (isset($_GET['delete'])) { $qsqri = bigintval($_GET['qsqri']); @@ -225,6 +304,70 @@ if ($questionnaire_id != false) if ($sample_import_id != false) { + if (isset($_POST['import_quota'])) + { + if (isset($_FILES['file']['tmp_name'])) + { + $handle = fopen($_FILES['file']['tmp_name'], "r"); + while (($data = fgetcsv($handle)) !== FALSE) + { + if (count($data) > 2) + { + //one quota record per row + $completions = intval($data[1]); + $autoprioritise = 0; + if ($data[2] != 0) $autoprioritise = 1; + $description = $db->quote($data[0]); + + $sql = "INSERT INTO questionnaire_sample_quota_row(questionnaire_id, sample_import_id, completions, description, priority, autoprioritise) + VALUES ($questionnaire_id, $sample_import_id, $completions, $description, 50, $autoprioritise)"; + + $db->Execute($sql); + + $qq = $db->Insert_ID(); + + if (count($data) > 5) //also some other records + { + //check if records exist (come in triplets + for ($i = 1; isset($data[$i * 3]) && !empty($data[$i*3]); $i++) + { + if (preg_match("/\d+X\d+X.+/",$data[$i*3])) + { + //is a limesurvey question + $comparison = $db->qstr($data[($i*3) + 1]); + $value = $db->qstr($data[($i*3) + 2]); + $sgqa = $db->qstr($data[$i*3]); + + $sql = "INSERT INTO qsqr_question (questionnaire_sample_quota_row_id,lime_sgqa,value,comparison) + VALUES ($qq,$sgqa,$value,$comparison)"; + + $db->Execute($sql); + } + else + { + //is a sample variable + $comparison = $db->qstr($data[($i*3) + 1]); + $value = $db->qstr($data[($i*3) + 2]); + $var = $db->qstr($data[$i*3]); + + $sql = "INSERT INTO qsqr_sample (questionnaire_sample_quota_row_id,exclude_var,exclude_val,comparison) + VALUES ($qq,$var,$value,$comparison)"; + + $db->Execute($sql); + } + } + } + + //Make sure to calculate on the spot + update_single_row_quota($qq); + } + } + fclose($handle); + } + } + + + if ($qsqri != false) { print "

" . T_("Quota") . ": $qsqrid

"; @@ -405,6 +548,15 @@ if ($questionnaire_id != false) "/>

" . T_("Import row quota") . ""; + ?> +
" method="post"> +

+

+

"/>

+
+ Date: Tue, 2 Jun 2015 12:31:13 +1000 Subject: [PATCH 9/9] Fix typo in SQL --- CHANGELOG | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 9a25c201..ddf611b6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -24,8 +24,8 @@ CREATE TABLE `qsqr_sample` ( INSERT INTO qsqr_question (questionnaire_sample_quota_row_id,lime_sgqa,value,comparison) SELECT questionnaire_sample_quota_row_id, lime_sgqa, value, comparison -FROM questionnaire_sample_quota_row; -WHERE lime_sgqa != -1 AND lime_sgqa != -2 +FROM questionnaire_sample_quota_row +WHERE lime_sgqa != -1 AND lime_sgqa != -2; INSERT INTO qsqr_sample (questionnaire_sample_quota_row_id,exclude_var,exclude_val,comparison) SELECT questionnaire_sample_quota_row_id, exclude_var,exclude_val, 'LIKE'