diff --git a/boost/boost.php b/boost/boost.php
new file mode 100644
index 0000000..b0690ad
--- /dev/null
+++ b/boost/boost.php
@@ -0,0 +1,15 @@
+
diff --git a/boost/controlpanel.php b/boost/controlpanel.php
new file mode 100644
index 0000000..f78f9b4
--- /dev/null
+++ b/boost/controlpanel.php
@@ -0,0 +1,34 @@
+
+*/
+
+$link[] = array(
+ 'label' => 'Student Legal Clinic Tracker 2.0',
+ 'restricted' => true,
+ 'url' => 'index.php?module=slc',
+ 'description' => 'Track statistics about visits',
+ 'image' => 'skeleton.png',
+ 'tab' => 'content'
+ );
+
+?>
diff --git a/boost/dependency.xml b/boost/dependency.xml
new file mode 100644
index 0000000..d51005b
--- /dev/null
+++ b/boost/dependency.xml
@@ -0,0 +1,9 @@
+
+
+
+ core
+ phpWebSite Core
+ 2.0.1
+ http://phpwebsite.appstate.edu/downloads/modules/base/
+
+
diff --git a/boost/uninstall.sql b/boost/uninstall.sql
new file mode 100644
index 0000000..ba5a60e
--- /dev/null
+++ b/boost/uninstall.sql
@@ -0,0 +1,41 @@
+-- slc - phpwebsite module
+-- @version $Id: $
+-- @author Adam Dixon
+
+DROP TABLE IF EXISTS slc_issue;
+
+DROP TABLE IF EXISTS slc_visit;
+
+DROP TABLE IF EXISTS slc_visit_issue_index;
+
+DROP TABLE IF EXISTS slc_visit_issue_date_index;
+
+DROP TABLE IF EXISTS slc_client;
+
+DROP TABLE IF EXISTS slc_visit_client_index;
+
+DROP TABLE IF EXISTS slc_issue_detail_index;
+
+DROP TABLE IF EXISTS slc_visit_detail_index;
+
+DROP TABLE IF EXISTS slc_client_detail_index;
+
+DROP TABLE IF EXISTS slc_detail;
+
+DROP TABLE IF EXISTS slc_landlord;
+
+DROP TABLE IF EXISTS slc_problem;
+
+DROP TABLE IF EXISTS slc_referral_type;
+
+DROP TABLE IF EXISTS slc_student_data;
+
+DROP TABLE IF EXISTS slc_visit_client_index_seq;
+DROP TABLE IF EXISTS slc_visit_issue_index_seq;
+DROP TABLE IF EXISTS slc_visit_seq;
+
+DROP TABLE IF EXISTS slc_issue_node;
+DROP TABLE IF EXISTS slc_issue_report;
+DROP TABLE IF EXISTS slc_issue_report_list;
+DROP TABLE IF EXISTS slc_issue_selected_node;
+DROP TABLE IF EXISTS slc_issue_seq;
diff --git a/boost/update.php b/boost/update.php
new file mode 100644
index 0000000..64b90a8
--- /dev/null
+++ b/boost/update.php
@@ -0,0 +1,131 @@
+
+ */
+
+function slc_update(&$content, $current_version) {
+ switch(1) {
+ case version_compare($current_version, '2.0.3', '<'):
+ $content[] = '
';
+
+ $db = new PHPWS_DB('slc_problem');
+ $db->addWhere('id', 16);
+ $db->addValue('description', 'Tenancy / Eviction');
+
+ if (PHPWS_Error::logIfError($db->update())) {
+ $content[] = 'Unable to change "Tenancy/Eviction" to "Tenancy / Eviction" in table slc_problem.';
+ return false;
+ } else {
+ $content[] = 'Changed "Tenancy/Eviction" to "Tenancy / Eviction" in table slc_problem';
+ }
+
+ slcUpdateFiles(array( 'class/ajax/GETReport.php',
+ 'class/views/ViewReports.php',
+ 'javascript/report/head.js',
+ 'templates/Report.tpl',
+ 'boost/install.sql',
+ 'boost/boost.php',
+ 'boost/update.php'), $content);
+
+ $content[] = '2.0.3 changes
+---------------
++ Added date selectors to all reports to limit data to a specific timespan.
++ Fixed the Landlord-Tenant report display issue in Firefox.
';
+
+ case version_compare($current_version, '2.0.4', '<'):
+ $content[] = '';
+
+ $db = new PHPWS_DB('slc_landlord');
+ $db->addWhere('id', 94);
+ $db->addValue('name', 'Other / Unspecified');
+ if (PHPWS_Error::logIfError($db->update())) {
+ $content[] = 'Unable to change "Other / Not Provided" to "Other / Unspecified" in table slc_landlord.';
+ return false;
+ }
+
+ $db->reset();
+ $db->addWhere('id', 70);
+ $db->addValue('name', 'Roger Pope');
+ if (PHPWS_Error::logIfError($db->update())) {
+ $content[] = 'Unable to move "Roger Pope" from id=95 to id=70';
+ return false;
+ }
+
+ $db->reset();
+ $db->addWhere('id', 95);
+ if (PHPWS_Error::logIfError($db->delete())) {
+ $content[] = 'Unable to delete Roger Pope\'s old id (95) from slc_landlord.';
+ return false;
+ }
+
+ $content[] = 'Successfully merged "Unknown" and "Other / Not Provided" into "Other / Unspecified" in table slc_landlord.';
+
+ $db = new PHPWS_DB('slc_issue');
+ $db->addWhere('landlord_id', 70);
+ $db->addValue('landlord_id', 94);
+ if (PHPWS_Error::logIfError($db->update())) {
+ $content[] = 'Unable to move issues assigned to landlord "Unknown" to landlord "Other / Unspecified".';
+ return false;
+ } else {
+ $content[] = 'Successfully moved issues assigned to landlord "Unknown" to landlord "Other / Unspecified".';
+ }
+
+ $db->reset();
+ $db->addWhere('landlord_id', 95);
+ $db->addValue('landlord_id', 70);
+ if (PHPWS_Error::logIfError($db->update())) {
+ $content[] = 'Unable to move issues assigned to landlord "Roger Pope" from his old id (95) to his new id (70).';
+ return false;
+ } else {
+ $content[] = 'Successfully moved issues assigned to landlord Roger Pope\'s old id (95) to his new id (70).';
+ }
+
+ slcUpdateFiles(array( 'boost/install.sql',
+ 'boost/update.php',
+ 'boost/boost.php',
+ 'class/ajax/GETReport.php',
+ 'class/ajax/POSTNewIssue.php'), $content);
+
+ $content[] = '2.0.4 changes
+---------------
++ Merged "Unknown" and "Other / Not Provided" landlords into "Other / Unspecified".
++ Updated the reports and issue creation to reflect this merging.';
+
+ case version_compare($current_version, '2.0.5', '<'):
+ $content[] = '';
+ slcUpdateFiles(array( 'boost/boost.php',
+ 'boost/update.php',
+ 'class/ajax/GETReport.php',
+ 'class/views/ViewReports.php',
+ 'javascript/report/head.js',
+ 'templates/Report.tpl',
+ 'class/ajax/ExportCSV.php'), $content);
+ $content[] = '2.0.5 changes
+---------------
++ Fixed some math issues in "Landlord/Tenant" and "Condition by Landlord" reports.
++ Added CSV export for the "Landlord/Tenant", "Condition by Landlord", and "Appointment Statistics" reports.
+';
+
+ case version_compare($current_version, '2.0.6', '<'):
+ $db = new PHPWS_DB;
+ $result = $db->importFile(PHPWS_SOURCE_DIR .
+ 'mod/slc/boost/updates/update_2_0_6.sql');
+ if(PHPWS_Error::logIfError($result)){
+ return $result;
+ }
+ }
+ return true;
+}
+
+function slcUpdateFiles($files, &$content) {
+ if (PHPWS_Boost::updateFiles($files, 'checkin')) {
+ $content[] = '--- Updated the following files:';
+ } else {
+ $content[] = '--- Unable to update the following files:';
+ }
+ $content[] = " " . implode("\n ", $files);
+}
+
+?>
diff --git a/boost/updates/update_2_0_6.sql b/boost/updates/update_2_0_6.sql
new file mode 100644
index 0000000..c3af00f
--- /dev/null
+++ b/boost/updates/update_2_0_6.sql
@@ -0,0 +1,62 @@
+-- Drop empty/unused/never-referenced tables
+DROP TABLE slc_client_detail_index,
+ slc_detail,
+ slc_issue_detail_index,
+ slc_visit_detail_index,
+ slc_visit_issue_date_index;
+
+-- Delete issue records with problem IDs that don't exist.
+DELETE slc_issue.*
+FROM slc_issue
+WHERE slc_issue.problem_id NOT IN (
+ SELECT slc_problem.id FROM slc_problem
+);
+
+-- Delete visit records with client IDs that don't exist.
+DELETE slc_visit.*
+FROM slc_visit
+WHERE slc_visit.c_id NOT IN (
+ SELECT id FROM slc_client
+);
+
+-- Delete slc_visit_issue_index records with issue IDs that don't exist.
+DELETE slc_visit_issue_index.*
+FROM slc_visit_issue_index
+WHERE slc_visit_issue_index.i_id NOT IN (
+ SELECT slc_issue.id FROM slc_issue
+);
+
+-- Delete slc_visit_issue_index records with visit IDs that don't exist.
+DELETE slc_visit_issue_index.*
+FROM slc_visit_issue_index
+WHERE slc_visit_issue_index.v_id NOT IN (
+ SELECT slc_visit.id FROM slc_visit
+);
+
+-- Delete visit records without an associated slc_visit_issue_index record.
+DELETE slc_visit.*
+FROM slc_visit
+WHERE slc_visit.id NOT IN (
+ SELECT v_id FROM slc_visit_issue_index
+);
+
+-- Delete issue records without an associated slc_visit_issue_index record.
+DELETE slc_issue.*
+FROM slc_issue
+WHERE slc_issue.id NOT IN (
+ SELECT i_id FROM slc_visit_issue_index
+);
+
+-- Then delete client records without associated visits.
+DELETE slc_client.*
+FROM slc_client
+WHERE slc_client.id NOT IN (
+ SELECT c_id FROM slc_visit
+);
+
+-- Merge all 'Criminal' sub-types into the main 'Criminal' type
+UPDATE slc_issue
+SET problem_id=998
+WHERE problem_id IN (
+ 25,26,27,28,29,30,31,32,33,34,995
+);
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..8928f73
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,146 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/class/AJAXFactory.php b/class/AJAXFactory.php
new file mode 100644
index 0000000..a35261d
--- /dev/null
+++ b/class/AJAXFactory.php
@@ -0,0 +1,53 @@
+call = new $action();
+ }
+
+ public function setData($data) {
+ $this->call->setData($data);
+ }
+
+ public function execute() {
+ $this->call->execute();
+ }
+
+ public function result() {
+ $this->result = $this->call->getResult();
+ return $this->result;
+ }
+
+
+}
+
+?>
diff --git a/class/Client.php b/class/Client.php
new file mode 100644
index 0000000..4575676
--- /dev/null
+++ b/class/Client.php
@@ -0,0 +1,20 @@
+id = $id;
+ }
+}
+
+?>
diff --git a/class/CommandContext.php b/class/CommandContext.php
new file mode 100644
index 0000000..b474f08
--- /dev/null
+++ b/class/CommandContext.php
@@ -0,0 +1,60 @@
+
+ * @package mod
+ * @subpackage slc
+ */
+
+class CommandContext {
+ private $params = array();
+ private $error = "";
+
+ function __construct() {
+ $this->params = $_REQUEST;
+ }
+
+ function addParam( $key, $val ) {
+ $this->params[$key]=$val;
+ }
+
+ function get( $key ) {
+ if(!isset($this->params[$key])){
+ throw new ParameterNotFoundException("Key: $key is not set");
+ }
+
+ return $this->params[$key];
+ }
+
+ function setError( $error ) {
+ $this->error = $error;
+ }
+
+ function getError() {
+ return $this->error;
+ }
+
+ function getParams() {
+ return $this->params;
+ }
+
+ function redirect($request){
+ $path = $_SERVER['SCRIPT_NAME'].'?module=slc';
+ foreach($request as $key=>$val) {
+ $path .= "&$key=$val";
+ }
+
+ header('HTTP/1.1 303 See Other');
+ header("Location: $path");
+ exit();
+ }
+}
+
+?>
diff --git a/class/Exceptions.php b/class/Exceptions.php
new file mode 100644
index 0000000..36f3d5b
--- /dev/null
+++ b/class/Exceptions.php
@@ -0,0 +1,27 @@
+
\ No newline at end of file
diff --git a/class/Issue.php b/class/Issue.php
new file mode 100644
index 0000000..aa6085a
--- /dev/null
+++ b/class/Issue.php
@@ -0,0 +1,25 @@
+id = $issueID;
+
+ }
+}
+
+?>
diff --git a/class/ViewFactory.php b/class/ViewFactory.php
new file mode 100644
index 0000000..4bae775
--- /dev/null
+++ b/class/ViewFactory.php
@@ -0,0 +1,37 @@
+
+ * @package mod
+ * @subpackage slc
+ */
+
+class ViewFactory {
+
+ public static function getView($view = 'Main'){
+ if ( preg_match( '/\W/', $view ) ) {
+ throw new Exception("Illegal characters in view");
+ }
+
+ $class = "View".$view;//UCFirst(strtolower($view));
+
+ $file = "{$class}.php";
+
+ if ( !PHPWS_Core::initModClass( 'slc', 'views/'.$file ) ) {
+ throw new ViewNotFoundException( "Could not find view '$file'" );
+ }
+
+ if ( ! class_exists( $class ) ) {
+ throw new ViewNotFoundException( "No view class '$class' located" );
+ }
+
+ $view = new $class();
+
+ return $view;
+ }
+}
+
+?>
diff --git a/class/Visit.php b/class/Visit.php
new file mode 100644
index 0000000..9ba3df6
--- /dev/null
+++ b/class/Visit.php
@@ -0,0 +1,18 @@
+issues[$issue->id] = $issue;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/class/ajax/AJAX.php b/class/ajax/AJAX.php
new file mode 100644
index 0000000..d716d60
--- /dev/null
+++ b/class/ajax/AJAX.php
@@ -0,0 +1,25 @@
+data = $data;
+ }
+
+ public function getResult() {
+ return $this->result;
+ }
+
+ protected function resetResult() {
+ $this->result = array();
+ }
+
+ protected function addResult($r, $v) {
+ $this->result[$r] = $v;
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/class/ajax/ExportCSV.php b/class/ajax/ExportCSV.php
new file mode 100644
index 0000000..116bc35
--- /dev/null
+++ b/class/ajax/ExportCSV.php
@@ -0,0 +1,393 @@
+
+ * @package SLC
+ */
+class ExportCSV extends AJAX {
+ public function execute() {
+ if (!isset($_REQUEST['report_type'])) {
+ $this->addResult("msg", "No Report Type Supplied");
+ return;
+ }
+
+ $csv;
+ $startdate = $_REQUEST['start_date'];
+ $enddate = $_REQUEST['end_date'];
+ $file = 'SLC' . $_REQUEST['report_type'] . ' ' . $startdate . ' to ' . $enddate . '.csv'; // output filename
+
+ $func = 'CSV' . $_REQUEST['report_type'];
+ if (method_exists("ExportCSV", $func)) {
+ $csv = call_user_func(array("ExportCSV", $func));
+ } else {
+ $csv = "The selected report is not available to be exported as a CSV file.";
+ echo $csv;
+ exit();
+ }
+
+ // Force the browser to open a 'save as' dialogue
+ header('Content-Type: text/csv');
+ header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
+ header('Pragma: public');
+ header('Expires: Mon, 17 Sep 2012 05:00:00 GMT'); // Date in the past
+ header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+ header('Content-Length: '.strlen($csv));
+ header('Content-Disposition: attachment; filename="' . $file . '";');
+
+ echo $csv;
+ exit();
+ }
+
+ /**
+ * Handles writing an array to a comma-separated string
+ *
+ * @param Array $row Array of values to write
+ * @param char $delimiter
+ * @param char $enclosure
+ * @param char $eol
+ */
+ private static function sputcsv(Array $row, $delimiter = ',', $enclosure = '"', $eol = "\n")
+ {
+ static $fp = false;
+ if ($fp === false)
+ {
+ $fp = fopen('php://temp', 'r+'); // see http://php.net/manual/en/wrappers.php.php - yes there are 2 '.php's on the end.
+ // NB: anything you read/write to/from 'php://temp' is specific to this filehandle
+ }
+ else
+ {
+ rewind($fp);
+ }
+
+ if (fputcsv($fp, $row, $delimiter, $enclosure) === false)
+ {
+ return false;
+ }
+
+ rewind($fp);
+ $csv = fgets($fp);
+
+ if ($eol != PHP_EOL)
+ {
+ $csv = substr($csv, 0, (0 - strlen(PHP_EOL))) . $eol;
+ }
+
+ return $csv;
+ }
+
+ /**
+ * Handles converting the 'Appointment Statistics' report to a CSV file
+ * Uses the same DB query as REPORTfollowupappts from GETReport.php
+ */
+ private function CSVfollowupappts() {
+ $initialVisits = 0;
+ $clients = 0;
+ $issues = 0;
+ $followups = 0;
+
+ // Get date range from user
+ $start_date = strtotime($_REQUEST['start_date']);
+ $end_date = strtotime($_REQUEST['end_date']) + 86400; // +1 day to make date range inclusive
+
+ // Get the array of all visits whose initial visit happened in the time period. Equivalent to this query:
+ // SELECT DISTINCT(id) FROM slc_visit WHERE initial_date >= $start_date AND initial_date < $end_date;
+ $db = new PHPWS_DB('slc_visit');
+ $db->addColumn('id', null, null, null, true);
+ $db->addWhere('initial_date', $start_date, '>=');
+ $db->addwhere('initial_date', $end_date, '<', 'AND');
+ $visitIds = $db->select('col');
+
+ // Get # of initial visits. Equivalent to this query:
+ // SELECT COUNT(DISTINCT(v_id)) FROM slc_visit_issue_index
+ // WHERE v_id IN $visitIds;
+ $db = new PHPWS_DB('slc_visit_issue_index');
+ $db->addColumn('v_id', null, null, true, true);
+ $db->addWhere('v_id', $visitIds, 'IN', 'AND');
+ $initialVisits = $db->select('one');
+
+ // Get the array of different 'counts' greater than 1. Equivalent to this query:
+ // SELECT DISTINCT(counter) FROM slc_visit_issue_index WHERE counter>'1' ORDER BY counter DESC;
+ $db->reset();
+ $db->addColumn('counter', null, null, null, true);
+ $db->addWhere('counter', '1', '>');
+ $db->addOrder('counter desc');
+ $counters = $db->select('col');
+
+ //TODO: Make followups only count if they occured during the time period.
+ // As of 05/20/2013 this is impossible due to the structure of the DB. We need to track when each followup occured.
+ // For now we just count all followups for visits whose initial visit took place within the time period.
+
+ // Calculate the number of followup visits.
+ $visits = array();
+ $db = new PHPWS_DB('slc_visit_issue_index');
+ $db->addColumn('v_id', null, null, null, true);
+ foreach ($counters as $count) {
+ $db->addWhere('v_id', $visitIds, 'IN');
+
+ // Make sure you don't count visits with multiple issues if they've already been counted.
+ if (!empty($visits)) {
+ $db->addWhere('v_id', $visits, 'NOT IN', 'AND');
+ }
+
+ $db->addWhere('counter', $count, '=', 'AND');
+ $result = $db->select('col');
+ $visits = $visits + $result;
+ $followups += ($count-1) * count($result);
+ $db->resetWhere();
+ }
+
+ // Get # of clients. Equivalent to this query:
+ // SELECT COUNT(DISTINCT(id)) FROM slc_client
+ // WHERE first_visit >= $start_date AND first_visit < $end_date;
+ $db = new PHPWS_DB('slc_client');
+ $db->addColumn('id', null, null, true, true);
+ $db->addWhere('first_visit', $start_date, '>=');
+ $db->addWhere('first_visit', $end_date, '<', 'AND');
+ $clients = $db->select('one');
+
+ // Get # of issues. Equivalent to this query:
+ // SELECT COUNT(DISTINCT(id)) FROM slc_issue
+ // JOIN slc_visit_issue_index ON slc_issue.id = slc_visit_issue_index.i_id
+ // WHERE slc_visit_issue_index.v_id IN $visitIds;
+ $db = new PHPWS_DB('slc_issue');
+ $db->addColumn('id', null, null, true, true);
+ $db->addTable('slc_visit_issue_index', 'svii');
+ $db->addWhere('slc_issue.id', 'svii.i_id');
+ $db->addWhere('svii.v_id', $visitIds, 'IN', 'AND');
+ $issues = $db->select('one');
+
+ // Put the data into the CSV.
+ $cols = array( 'Total Clients',
+ 'Total Issues',
+ 'Total Initial Visits',
+ 'Total Followups',
+ 'Issues per Visit (w/o Followups)',
+ 'Visits per Client (w/o Followups)',
+ 'Visits per Client (with Followups)',
+ 'Followups per Issue',
+ 'Followups per Visit');
+ $rows = array( $clients,
+ $issues,
+ $initialVisits,
+ $followups,
+ ($clients == 0 ? 0 : round($issues / $initialVisits, 2)),
+ ($clients == 0 ? 0 : round($initialVisits / $clients, 2)),
+ ($clients == 0 ? 0 : round(($initialVisits + $followups) / $clients, 2)),
+ ($clients == 0 ? 0 : round($followups / $issues, 2)),
+ ($clients == 0 ? 0 : round($followups / $initialVisits, 2)));
+ $data = $this->sputcsv($cols);
+ $data .= $this->sputcsv($rows);
+
+ return $data;
+ }
+
+ /**
+ * Handles converting the 'Landlord/Tenant' report to a CSV file
+ * Uses the same DB query as REPORTlandlordtenant from GETReport.php
+ */
+ private function CSVlandlordtenant() {
+ // Get date range from user
+ $start_date = strtotime($_REQUEST['start_date']);
+ $end_date = strtotime($_REQUEST['end_date']) + 86400; // +1 day to make date range inclusive
+
+ $landlords = "SELECT * FROM slc_landlord";
+ $db = new PHPWS_DB();
+ $landlords = $db->select(null, $landlords);
+ $landlordnames = array();
+ foreach( $landlords as $landlord )
+ $landlordnames[] = $landlord['name'];
+
+ $issues = "SELECT * FROM slc_problem WHERE tree LIKE '%Landlord-Tenant%' OR description LIKE 'Conditions' OR description LIKE 'Landlord-Tenant' "; // Covers generic landlord-tenant, too
+ $db = new PHPWS_DB();
+ $issues = $db->select(null, $issues);
+ $issuenames = array();
+ foreach( $issues as $issue )
+ $issuenames[] = $issue['description'];
+
+
+ // Get the issues listed ( all others 0 )
+ $db = new PHPWS_DB();
+ $db->addTable('slc_issue');
+ $db->addTable('slc_problem');
+ $db->addTable('slc_landlord');
+ $db->addTable('slc_visit');
+ $db->addTable('slc_visit_issue_index');
+ $db->addColumn('slc_problem.description');
+ $db->addColumn('slc_landlord.name');
+
+ // 1st Join set
+ // needs to be a left join to allow for landlord "not specified" which is recorded as NULL in DB
+ $db->addJoin('left', 'slc_issue', 'slc_landlord', 'landlord_id', 'id');
+
+ // 2nd Join set
+ $db->addJoin('inner', 'slc_problem', 'slc_issue', 'id', 'problem_id');
+ $db->addJoin('inner', 'slc_issue', 'slc_visit_issue_index', 'id', 'i_id');
+ $db->addJoin('inner', 'slc_visit_issue_index', 'slc_visit', 'v_id', 'id');
+ $db->addWhere('slc_visit.initial_date', $start_date, '>=');
+ $db->addWhere('slc_visit.initial_date', $end_date, '<', 'AND');
+ $results = $db->select();
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ $theMatrix = $landlordnames;
+ foreach($landlordnames as $lname) {
+ $theMatrix[$lname] = $issuenames;
+ foreach($issuenames as $iname)
+ $theMatrix[$lname][$iname] = 0; // Populate with 0s
+ }
+
+
+ foreach( $results as $r ) {
+ // If landlord name is NULL, set as "Other / Unspecified"
+ $name = isset($r['name']) ? $r['name'] : "Other / Unspecified";
+ $description = $r['description'];
+
+ if ( !array_key_exists($description,$theMatrix[$name]) )
+ $theMatrix[$name][$description] = 0;
+
+ $theMatrix[$name][$description]++; // increment that value
+ }
+
+ // Create the final $data array
+ $data = $this->sputcsv(array_merge(array_merge(array(' '), $issuenames), array('Landlord Totals')));
+
+ $colTotals = array();
+ foreach ($landlordnames as $landlord) {
+ $row = array($landlord);
+ $accumulator = 0;
+ foreach ($issuenames as $issue) {
+ $value = $theMatrix[$landlord][$issue];
+ $row[] = $value;
+ $accumulator += $value;
+ if (!array_key_exists($issue, $colTotals)) {
+ $colTotals[$issue] = 0;
+ }
+ $colTotals[$issue] += $value;
+ }
+ $row[] = $accumulator;
+ $data .= $this->sputcsv($row);
+ }
+
+ $totalRow = array('Issue Totals');
+ $accumulator = 0;
+ foreach ($issuenames as $issue) {
+ if (array_key_exists($issue, $colTotals)) {
+ $totalRow[] = $colTotals[$issue];
+ $accumulator += $colTotals[$issue];
+ }
+ }
+ $totalRow[] = $accumulator;
+ $data .= $this->sputcsv($totalRow);
+
+ return $data;
+ }
+
+ /**
+ * Handles converting the 'Condition by Landlord' report to a CSV file
+ * Uses the same DB query as REPORTconditionbylandlord from GETReport.php
+ */
+ private function CSVconditionbylandlord() {
+ // Get date range from user
+ $start_date = strtotime($_REQUEST['start_date']);
+ $end_date = strtotime($_REQUEST['end_date']) + 86400; // +1 day to make date range inclusive
+
+ $landlords = "SELECT * FROM slc_landlord";
+ $db = new PHPWS_DB();
+ $landlords = $db->select(null, $landlords);
+ $landlordnames = array();
+ foreach( $landlords as $landlord )
+ $landlordnames[] = $landlord['name'];
+
+ $issues = "SELECT * FROM slc_problem WHERE type LIKE 'Conditions' "; // Covers generic landlord-tenant, too
+ $db = new PHPWS_DB();
+ $issues = $db->select(null, $issues);
+ $issuenames = array();
+ foreach( $issues as $issue )
+ $issuenames[] = $issue['description'];
+ $issuenames[] = "Conditions";
+
+ // Get the issues listed ( all others 0 )
+ $db = new PHPWS_DB();
+ $db->addTable('slc_issue');
+ $db->addTable('slc_problem');
+ $db->addTable('slc_landlord');
+ $db->addTable('slc_visit');
+ $db->addTable('slc_visit_issue_index');
+ $db->addColumn('slc_problem.description');
+ $db->addColumn('slc_landlord.name');
+
+ // 1st Join set
+ // needs to be a left join to allow for landlord "not specified" which is recorded as NULL in DB
+ $db->addJoin('left', 'slc_issue', 'slc_landlord', 'landlord_id', 'id');
+
+ // 2nd Join set
+ $db->addJoin('inner', 'slc_problem', 'slc_issue', 'id', 'problem_id');
+ $db->addJoin('inner', 'slc_issue', 'slc_visit_issue_index', 'id', 'i_id');
+ $db->addJoin('inner', 'slc_visit_issue_index', 'slc_visit', 'v_id', 'id');
+
+ // WHERE (type LIKE "Conditions" OR description LIKE "Conditions") AND initial_date BETWEEN $start_date AND $end_date
+ $db->addWhere('slc_problem.type', 'Conditions', 'LIKE', NULL, 'conditions');
+ $db->addWhere('slc_problem.description', 'Conditions', 'LIKE', 'OR', 'conditions');
+ $db->addWhere('slc_visit.initial_date', $start_date, '>=', 'AND');
+ $db->addWhere('slc_visit.initial_date', $end_date, '<', 'AND');
+ $results = $db->select();
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ $theMatrix = $landlordnames;
+ foreach($landlordnames as $lname) {
+ $theMatrix[$lname] = $issuenames;
+ foreach($issuenames as $iname)
+ $theMatrix[$lname][$iname] = 0; // Populate with 0s
+ }
+
+ foreach( $results as $r ) {
+ // If landlord name is NULL, set as "Other / Unspecified"
+ $name = isset($r['name']) ? $r['name'] : "Other / Unspecified";
+ $description = $r['description'];
+
+ $theMatrix[$name][$description]++; // increment that value
+ }
+
+ // Create the final $data array
+ $data = $this->sputcsv(array_merge(array_merge(array(' '), $issuenames), array('Landlord Total')));
+
+ $colTotals = array();
+ foreach ($landlordnames as $landlord) {
+ $row = array($landlord);
+ $accumulator = 0;
+ foreach ($issuenames as $issue) {
+ $value = $theMatrix[$landlord][$issue];
+ $row[] = $value;
+ $accumulator += $value;
+ if (!array_key_exists($issue, $colTotals)) {
+ $colTotals[$issue] = 0;
+ }
+ $colTotals[$issue] += $value;
+ }
+ $row[] = $accumulator;
+ $data .= $this->sputcsv($row);
+ }
+
+ $totalRow = array('Issue Totals');
+ $accumulator = 0;
+ foreach ($issuenames as $issue) {
+ if (array_key_exists($issue, $colTotals)) {
+ $totalRow[] = $colTotals[$issue];
+ $accumulator += $colTotals[$issue];
+ }
+ }
+ $totalRow[] = $accumulator;
+ $data .= $this->sputcsv($totalRow);
+
+ return $data;
+ }
+}
+?>
diff --git a/class/ajax/GETClientData.php b/class/ajax/GETClientData.php
new file mode 100644
index 0000000..616dc4d
--- /dev/null
+++ b/class/ajax/GETClientData.php
@@ -0,0 +1,104 @@
+addResult("msg", "No ID Supplied");
+// throw new IDNotSuppliedException();
+ return;
+ }
+
+ $client = new Client();
+
+ // check if it's already encoded
+ if ( !startsWith($_REQUEST['banner_id'], "$") ) {
+
+ unset($_SESSION['cname']);
+
+ // Grab extra information from ASU Database
+ $db = new PHPWS_DB('slc_student_data');
+ $db->addWhere("id", $_REQUEST['banner_id']);
+ $results = $db->loadObject($tClient);
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ $this->addResult("msg", "Database Exception");
+ return;
+ }
+
+ if ( !$results ) {
+ $this->addResult("msg", "Client not in ASU Database");
+ return;
+ }
+
+
+ // Store the name in session, as after the banner is encrypted, there's no way to get it
+ $_SESSION['cname'] = serialize($tClient->fname . ' ' . $tClient->lname);
+
+ // encode banner
+ $_REQUEST['banner_id'] = encode($_REQUEST['banner_id']);
+ }
+
+ $banner = $_REQUEST['banner_id'];
+
+ //$client = new Client($banner);
+ $client->id = $banner;
+
+
+
+ // check that client exists in database
+ $db = new PHPWS_DB($this->_table);
+ $results = $db->loadObject($client);
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ $this->addResult("msg", "Database Exception");
+ return;
+ }
+
+ if ( !$results ) {
+ $this->addResult("msg", "Client does not exist");
+
+ // create new client
+ $ajax = AjaxFactory::get("newClient");
+ $ajax->loadCall("POSTNewClient");
+ $ajax->setData(array("classification"=>$tClient->classification, "major"=>$tClient->major, "living_location"=>$tClient->living_location));
+ $ajax->execute();
+ $client = $ajax->result();
+
+ $client = $client['client'];
+ $this->addResult('newFlag', true);
+ } else
+ $this->addResult('newFlag', false);
+ $client->fname = $tClient->fname;
+ $client->lname = $tClient->lname;
+ $client->name = $client->fname . ' ' . $client->lname;
+
+ // Check if existing client has referral set
+ if ( isset($client->referral) ) {
+ // Add actual text of referral into client
+ $query = 'SELECT * '.
+ ' FROM slc_referral_type '.
+ ' WHERE id=' . $client->referral;
+
+ $db = new PHPWS_DB();
+ //$db->setTestMode();
+ $results = $db->select(null, $query);
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+ //test($results);
+ $client->referralString = $results[0]["name"];
+ $this->addResult('referralSet', true);
+ } else
+ $this->addResult('referralSet', false);
+
+
+ $this->addResult("client", $client);
+
+ }
+}
diff --git a/class/ajax/GETClientVisits.php b/class/ajax/GETClientVisits.php
new file mode 100644
index 0000000..2f9d2e9
--- /dev/null
+++ b/class/ajax/GETClientVisits.php
@@ -0,0 +1,98 @@
+addResult("msg", "No ID Supplied");
+// throw new IDNotSuppliedException();
+ return;
+ }
+
+ $banner = $_REQUEST['banner_id'];
+
+ $client = new Client($banner);
+
+ // check that client exists in database, if not create
+ $db = new PHPWS_DB("slc_client");
+ $results = $db->loadObject($client);
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ if ( !$results ) {
+ $this->addResult("msg", "Client does not exist");
+ return;
+ }
+
+ $query = 'SELECT v.id as "VISITID", v.initial_date as "INITIALDATE"'.
+ ' FROM slc_visit as v'.
+ ' WHERE v.c_id = "'.$client->id.'"';
+
+ $db = new PHPWS_DB();
+ //$db->setTestMode();
+ $results = $db->select(null, $query);
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ $visits = null;
+ //test($results);
+ foreach( $results as $r ) { // visits
+ $vid = $r['VISITID'];
+
+ if (!isset($visits[$vid])) {
+ // test("Creating new visit for id: ".$vid);
+ $visits[$vid] = new Visit();
+ }
+
+ $visit = $visits[$vid];
+ $visit->id = $vid;
+ $visit->initial_date = $r['INITIALDATE'];
+ $visit->client_id = $client->id;
+
+
+
+ // issues
+ $query = 'SELECT vii.id AS "VIIID", p.description AS "ISSUENAME", l.name as "LANDLORDNAME", i.landlord_id as "LANDLORDID", i.problem_id as "PROBLEMID", vii.i_id AS "ISSUEID", vii.counter AS "COUNTER", vii.resolve_date AS "RESOLVEDATE", vii.last_access AS "LASTACCESS"'.
+ ' FROM slc_visit_issue_index as vii'.
+ ' INNER JOIN slc_issue i ON vii.i_id=i.id'.
+ ' INNER JOIN slc_problem p ON i.problem_id=p.id'.
+ ' LEFT JOIN (slc_landlord l) ON (i.landlord_id = l.id)'.
+ ' WHERE vii.v_id = "'.$vid.'"';
+
+
+ $db = new PHPWS_DB();
+ $iresults = $db->select(null, $query);
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ foreach( $iresults as $ir ) { // visits
+ // set up issue
+ $issue = new Issue($ir['ISSUEID']);
+ $issue->name = $ir['ISSUENAME'];
+ $issue->last_access = $ir['LASTACCESS'];
+ $issue->counter = $ir['COUNTER'];
+ $issue->resolution_date = $ir['RESOLVEDATE'];
+ $issue->visit_issue_id = $ir['VIIID'];
+ $issue->problem_id = $ir['PROBLEMID'];
+ $issue->landlord_id = $ir['LANDLORDID'];
+ $issue->landlord_name = (isset($issue->landlord_id)) ? " with ".$ir['LANDLORDNAME'] : null;
+
+ // add issue
+ $visit->addIssue($issue);
+ }
+
+ //test($visit);
+
+ //$visits[$vid] = $visit;
+ }
+
+ $this->addResult("visits", $visits);
+ }
+}
+?>
diff --git a/class/ajax/GETReferralBox.php b/class/ajax/GETReferralBox.php
new file mode 100644
index 0000000..7a1a854
--- /dev/null
+++ b/class/ajax/GETReferralBox.php
@@ -0,0 +1,27 @@
+setTestMode();
+ $results = $db->select(null, $query);
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ $rTypes = array();
+ foreach( $results as $r ) { // types
+ $rTypes[] = array("REFERRAL_ID" => $r['id'], "NAME"=>$r['name']);
+ }
+
+ $referralPicker = PHPWS_Template::process(array("referrals"=>$rTypes), 'slc', 'ReferralPicker.tpl');
+
+ $this->addResult("referral_picker", $referralPicker);
+ }
+}
diff --git a/class/ajax/GETReport.php b/class/ajax/GETReport.php
new file mode 100644
index 0000000..4e7279d
--- /dev/null
+++ b/class/ajax/GETReport.php
@@ -0,0 +1,869 @@
+addResult("msg", "No Report Type Supplied");
+ // throw new ReportTypeNotSuppliedException();
+ return;
+ }
+
+ $reportHTML = "";
+
+ $func = 'REPORT'.$_REQUEST['report_type'];
+
+ if ( method_exists("GETReport", $func) )
+ $reportHTML .= call_user_func(array("GETReport", $func));
+ else
+ $reportHTML .= "The selected report type (".$_REQUEST['report_type'].") is not yet implemented in this version";
+
+ $this->addResult('report_html', $reportHTML);
+ }
+
+ function REPORTstudentsseen() {
+ $query = "SELECT ";
+ $query .= "(SELECT COUNT(DISTINCT id) FROM slc_visit) AS visits, ";
+ $query .= "(SELECT COUNT(DISTINCT id) FROM slc_client) AS clients, ";
+ $query .= "(SELECT COUNT(DISTINCT id) FROM slc_issue) AS issues, ";
+ $query .= "(SELECT SUM(counter) FROM slc_visit_issue_index) AS followups ";
+
+ $db = new PHPWS_DB();
+ //$db->setTestMode();
+ $results = $db->select(null, $query);
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ $results = $results[0]; // since it's a count, should always return a number
+ $visits = $results['visits'];
+ $clients = $results['clients'];
+ $issues = $results['issues'];
+ $followups = $results['followups'] - $issues; // Every issue has at least one visit, so remove initial
+
+ $bgcolor = array(0=>"#FFFFFF",1=>"#FFEC8B");
+ $r = 0;
+
+ $html = "";
+ $html .= "
";
+ $html .= "Situation | Record |
";
+ $html .= "Total Visits | ".$visits." |
"; $r = !$r;
+ $html .= "Total Clients | ".$clients." |
"; $r = !$r;
+ $html .= "Total Issues | ".$issues." |
"; $r = !$r;
+ $html .= "Visits per Client | ".(round($visits/$clients,2))." |
"; $r = !$r;
+ $html .= "Issues per Visit | ".(round($issues/$visits,2))." |
"; $r = !$r;
+ $html .= "Followups per Issue | ".(round($followups/$issues, 2))." |
"; $r = !$r;
+ $html .= "
";
+
+ return $html;
+ }
+
+ /**
+ * This method builds the Intake by Problem Type report.
+ */
+ private function REPORTintakebyproblemtype() {
+ // Get date range from user
+ $start_date = strtotime($_REQUEST['start_date']);
+ $end_date = strtotime($_REQUEST['end_date']) + 86400; // +1 day to make date range inclusive
+
+ // Get the list of all Landlord-Tenant type problems
+ $db = new PHPWS_DB('slc_problem');
+ $db->addColumn('description');
+ $db->addWhere('type', 'Landlord-Tenant', 'LIKE');
+ $landlord = $db->select();
+
+ if(PHPWS_Error::logIfError($landlord)){
+ throw new DatabaseException();
+ }
+
+ // Get the list of all Conditions type problems
+ $db = new PHPWS_DB('slc_problem');
+ $db->addColumn('description');
+ $db->addWhere('type', 'Conditions', 'LIKE');
+ $conditions = $db->select();
+
+ if(PHPWS_Error::logIfError($conditions)){
+ throw new DatabaseException();
+ }
+
+ $db = new PHPWS_DB();
+ $db->addTable('slc_issue');
+ $db->addTable('slc_problem');
+ $db->addTable('slc_visit');
+ $db->addTable('slc_visit_issue_index');
+ $db->addColumn('slc_issue.id', NULL, 'count', TRUE, TRUE);
+ $db->addColumn('slc_problem.description');
+ $db->addJoin('inner', 'slc_issue', 'slc_problem', 'problem_id', 'id');
+ $db->addJoin('inner', 'slc_issue', 'slc_visit_issue_index', 'id', 'i_id');
+ $db->addJoin('inner', 'slc_visit', 'slc_visit_issue_index', 'id', 'v_id');
+ $db->addWhere('slc_visit.initial_date', $start_date, '>=');
+ $db->addWhere('slc_visit.initial_date', $end_date, '<', 'AND');
+ $db->addGroupBy('slc_issue.problem_id');
+ $results = $db->select();
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ /*
+ * Remove all Landlord-Tenant and Conditions type problems from the main
+ * results array, seperate them into individual arrays, and tally the
+ * number of problems recorded for each. Also grab the generic
+ * Landlord-Tenant and Conditions types, tally their occurences, and put
+ * them at the head of the proper set of results.
+ */
+ $landlordCount = 0;
+ $conditionsCount = 0;
+ $landlordResults = array(array('description'=>'Landlord-Tenant', 'count'=>$landlordCount));
+ $conditionsResults = array(array('description'=>'Conditions', 'count'=>$conditionsCount));
+
+ // Find generic problem types first and list them as the first sub-type
+ foreach($results as $key=>$r) {
+ if ($r['description'] == 'Landlord-Tenant') { // generic type
+ $r['description'] = 'Generic Landlord-Tenant';
+ $landlordResults[] = $r;
+ $landlordCount += $r['count'];
+ unset($results[$key]);
+ } elseif ($r['description'] == 'Conditions') { // generic type
+ $r['description'] = 'Generic Condition';
+ $conditionsResults[] = $r;
+ $conditionsCount += $r['count'];
+ unset($results[$key]);
+ }
+ }
+
+ foreach($results as $key=>$r) {
+ if(in_array(array('description'=>$r['description']), $landlord, TRUE)) {
+ $landlordResults[] = $results[$key];
+ $landlordCount += $r['count'];
+ unset($results[$key]);
+ } elseif (in_array(array('description'=>$r['description']), $conditions, TRUE)) {
+ $conditionsResults[] = $results[$key];
+ $conditionsCount += $r['count'];
+ unset($results[$key]);
+ }
+ }
+
+ // re-index the main results array now that we have removed all landlord and conditions results
+ $results = array_values($results);
+
+ // If there are Conditions type problems, nest them in the Landlord-Tenant
+ // results and include their total occurences in the Landlord-Tenant count.
+ if ($conditionsCount > 0) {
+ $conditionsResults[0]['count'] = $conditionsCount;
+
+ // Use the generic Conditions problem as the main line for all Conditions problems
+ $landlordResults[] = $conditionsResults[0];
+ $landlordCount += $conditionsCount;
+ $landlordResults[0]['count'] = $landlordCount;
+ unset($conditionsResults[0]);
+
+ // Indent all sub-types of Conditions problems
+ foreach ($conditionsResults as $r3) {
+ $string = "-> " . $r3['description'];
+ $landlordResults[] = array('description'=>$string, 'count'=>$r3['count']);
+ }
+ }
+
+ // If there are Landlord-Tenant type problems, nest them in the main results array
+ if ($landlordCount > 0) {
+ $landlordResults[0]['count'] = $landlordCount;
+
+ // Use the generic Landlord-Tenant problem as the main line for all Landlord-Tenant problems
+ $results[] = $landlordResults[0];
+ unset($landlordResults[0]);
+
+ // Indent all sub-types of Landlord-Tenant problems
+ foreach ($landlordResults as $r2) {
+ if (substr($r2['description'], 0, 2) === '->') {
+ // Don't add a second '-> ' to Conditions type problems
+ $string = " " . $r2['description'];
+ } else {
+ $string = "-> " . $r2['description'];
+ }
+ $results[] = array('description'=>$string, 'count'=>$r2['count']);
+ }
+ }
+
+ $html = "";
+
+ if (count($results) != 0) { // Return the empty string if there are no results
+ $html .= "";
+ $html .= "Situation | Record |
";
+ $bgcolor = array(0=>"#FFFFFF",1=>"#FFEC8B");
+ $rc = 0;
+ $total = 0;
+
+ foreach( $results as $r ) {
+ $count = $r['count'];
+
+ // Don't include counts for sub-categories in the total count, we have already counted those.
+ if (strpos($r['description'], '->') === FALSE) {
+ $total += $count;
+ }
+
+ $type = $r['description'];
+
+ $html .= "".$type." | ".$count." |
";
+ $rc = !$rc;
+ }
+
+ // Add a final row with the total # of problems
+ $html .= "Total Number Of Problems | ".$total." |
";
+ $html .= "
";
+ }
+
+ return $html;
+ }
+
+ private function REPORTlandlordtenant() {
+ // Get date range from user
+ $start_date = strtotime($_REQUEST['start_date']);
+ $end_date = strtotime($_REQUEST['end_date']) + 86400; // +1 day to make date range inclusive
+
+ $landlords = "SELECT * FROM slc_landlord";
+ $db = new PHPWS_DB();
+ $landlords = $db->select(null, $landlords);
+ $landlordnames = array();
+ foreach( $landlords as $landlord )
+ $landlordnames[] = $landlord['name'];
+
+ $issues = "SELECT * FROM slc_problem WHERE tree LIKE '%Landlord-Tenant%' OR description LIKE 'Conditions' OR description LIKE 'Landlord-Tenant' "; // Covers generic landlord-tenant, too
+ $db = new PHPWS_DB();
+ $issues = $db->select(null, $issues);
+ $issuenames = array();
+ foreach( $issues as $issue )
+ $issuenames[] = $issue['description'];
+
+
+ // Get the issues listed ( all others 0 )
+ $db = new PHPWS_DB();
+ $db->addTable('slc_issue');
+ $db->addTable('slc_problem');
+ $db->addTable('slc_landlord');
+ $db->addTable('slc_visit');
+ $db->addTable('slc_visit_issue_index');
+ $db->addColumn('slc_problem.description');
+ $db->addColumn('slc_landlord.name');
+
+ // 1st Join set
+ // needs to be a left join to allow for landlord "not specified" which is recorded as NULL in DB
+ $db->addJoin('left', 'slc_issue', 'slc_landlord', 'landlord_id', 'id');
+
+ // 2nd Join set
+ $db->addJoin('inner', 'slc_problem', 'slc_issue', 'id', 'problem_id');
+ $db->addJoin('inner', 'slc_issue', 'slc_visit_issue_index', 'id', 'i_id');
+ $db->addJoin('inner', 'slc_visit_issue_index', 'slc_visit', 'v_id', 'id');
+ $db->addWhere('slc_visit.initial_date', $start_date, '>=');
+ $db->addWhere('slc_visit.initial_date', $end_date, '<', 'AND');
+ $results = $db->select();
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ $theMatrix = $landlordnames;
+ foreach($landlordnames as $lname) {
+ $theMatrix[$lname] = $issuenames;
+ foreach($issuenames as $iname)
+ $theMatrix[$lname][$iname] = 0; // Populate with 0s
+ }
+
+
+ foreach( $results as $r ) {
+ // If landlord name is NULL, set as "Other / Unspecified"
+ $name = isset($r['name']) ? $r['name'] : "Other / Unspecified";
+ $description = $r['description'];
+
+ if ( !array_key_exists($description,$theMatrix[$name]) )
+ $theMatrix[$name][$description] = 0;
+
+ $theMatrix[$name][$description]++; // increment that value
+ }
+
+ // Row Colors
+ $stripes = array(0=>"255,255,255",1=>"255,236,139");
+ $zebra = 0;
+
+ $html = "";
+
+ // Header Row
+ $html .= " | ";
+ $col = 1;
+ foreach ($issuenames as $issue) {
+ $html .= "" . $issue . " | ";
+ }
+ $html .= "Landlord Total |
";
+
+ // Table Body
+ $colTotals = array();
+ $row = 1;
+ foreach ($landlordnames as $landlord) {
+ $col = 0;
+ $html .= "" . $landlord . " | ";
+
+ $rowTotal = 0;
+ foreach ($issuenames as $issue) {
+ $value = $theMatrix[$landlord][$issue];
+ $style = ($value == 0) ? "color:#ABABAB;" : "color:#000000; font-weight:bold;";
+
+ $html .= "" . $value . " | ";
+ $rowTotal += $value;
+
+ // Increment the column total
+ if (array_key_exists($issue, $colTotals)) {
+ $colTotals[$issue] += $value;
+ } else {
+ $colTotals[$issue] = $value;
+ }
+ }
+
+ $html .= "" . $rowTotal . " | ";
+
+ $row++;
+ $zebra = !$zebra; // flip the row color
+ }
+
+ // Condition Totals Row
+ $html .= "
Condition Total | ";
+ $col = 1;
+ $rowTotal = 0;
+ foreach ($colTotals as $val) {
+ $html .= "" . $val . " | ";
+ $rowTotal += $val;
+ }
+ $html .= "" . $rowTotal . " |
";
+
+
+ $html .= "
";
+ return $html;
+ }
+
+ private function REPORTconditionbylandlord() {
+ // Get date range from user
+ $start_date = strtotime($_REQUEST['start_date']);
+ $end_date = strtotime($_REQUEST['end_date']) + 86400; // +1 day to make date range inclusive
+
+ $landlords = "SELECT * FROM slc_landlord";
+ $db = new PHPWS_DB();
+ $landlords = $db->select(null, $landlords);
+ $landlordnames = array();
+ foreach( $landlords as $landlord )
+ $landlordnames[] = $landlord['name'];
+
+ $issues = "SELECT * FROM slc_problem WHERE type LIKE 'Conditions' "; // Covers generic landlord-tenant, too
+ $db = new PHPWS_DB();
+ $issues = $db->select(null, $issues);
+ $issuenames = array();
+ foreach( $issues as $issue )
+ $issuenames[] = $issue['description'];
+ $issuenames[] = "Conditions";
+
+ // Get the issues listed ( all others 0 )
+ $db = new PHPWS_DB();
+ $db->addTable('slc_issue');
+ $db->addTable('slc_problem');
+ $db->addTable('slc_landlord');
+ $db->addTable('slc_visit');
+ $db->addTable('slc_visit_issue_index');
+ $db->addColumn('slc_problem.description');
+ $db->addColumn('slc_landlord.name');
+
+ // 1st Join set
+ // needs to be a left join to allow for landlord "not specified" which is recorded as NULL in DB
+ $db->addJoin('left', 'slc_issue', 'slc_landlord', 'landlord_id', 'id');
+
+ // 2nd Join set
+ $db->addJoin('inner', 'slc_problem', 'slc_issue', 'id', 'problem_id');
+ $db->addJoin('inner', 'slc_issue', 'slc_visit_issue_index', 'id', 'i_id');
+ $db->addJoin('inner', 'slc_visit_issue_index', 'slc_visit', 'v_id', 'id');
+
+ // WHERE (type LIKE "Conditions" OR description LIKE "Conditions") AND initial_date BETWEEN $start_date AND $end_date
+ $db->addWhere('slc_problem.type', 'Conditions', 'LIKE', NULL, 'conditions');
+ $db->addWhere('slc_problem.description', 'Conditions', 'LIKE', 'OR', 'conditions');
+ $db->addWhere('slc_visit.initial_date', $start_date, '>=', 'AND');
+ $db->addWhere('slc_visit.initial_date', $end_date, '<', 'AND');
+ $results = $db->select();
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+ $html = "";
+
+ $theMatrix = $landlordnames;
+ foreach($landlordnames as $lname) {
+ $theMatrix[$lname] = $issuenames;
+ foreach($issuenames as $iname)
+ $theMatrix[$lname][$iname] = 0; // Populate with 0s
+ }
+
+
+ foreach( $results as $r ) {
+ // If landlord name is NULL, set as "Other / Unspecified"
+ $name = isset($r['name']) ? $r['name'] : "Other / Unspecified";
+ $description = $r['description'];
+
+ $theMatrix[$name][$description]++; // increment that value
+ }
+
+ // Row Colors
+ $stripes = array(0=>"255, 255, 255", 1=>"255, 236, 139");
+ $zebra = 0;
+
+ $html .= "";
+
+ // Header Row
+ $html .= " | ";
+ $col = 1;
+ foreach ($issuenames as $issue) {
+ $html .= "" . $issue . " | ";
+ }
+ $html .= "Landlord Total |
";
+
+ // Table Body
+ $colTotals = array();
+ $row = 1;
+ foreach ($landlordnames as $landlord) {
+ $col = 0;
+ $html .= "" . $landlord . " | ";
+
+ $rowTotal = 0;
+ foreach ($issuenames as $issue) {
+ $value = $theMatrix[$landlord][$issue];
+ $style = ($value == 0) ? "color:#ABABAB;" : "color:#000000; font-weight:bold;";
+
+ $html .= "" . $value . " | ";
+ $rowTotal += $value;
+
+ // Increment the column total
+ if (array_key_exists($issue, $colTotals)) {
+ $colTotals[$issue] += $value;
+ } else {
+ $colTotals[$issue] = $value;
+ }
+ }
+
+ $html .= "" . $rowTotal . " | ";
+
+ $row++;
+ $zebra = !$zebra; // flip the row color
+ }
+
+ // Condition Totals Row
+ $html .= "
Condition Total | ";
+ $col = 1;
+ $rowTotal = 0;
+ foreach ($colTotals as $val) {
+ $html .= "" . $val . " | ";
+ $rowTotal += $val;
+ }
+ $html .= "" . $rowTotal . " |
";
+
+
+ $html .= "
";
+ return $html;
+ }
+
+ private function REPORTproblembyyear() {
+ // Get date range from user
+ $start_date = strtotime($_REQUEST['start_date']);
+ $end_date = strtotime($_REQUEST['end_date']) + 86400; // +1 day to make date range inclusive
+
+ $db = new PHPWS_DB();
+ $db->addTable('slc_visit_issue_index');
+ $db->addTable('slc_visit');
+ $db->addTable('slc_client');
+ $db->addTable('slc_issue');
+ $db->addTable('slc_problem');
+ $db->addColumn('slc_client.classification');
+ $db->addColumn('slc_problem.description');
+ $db->addColumn('slc_problem.tree');
+ $db->addJoin('inner', 'slc_visit_issue_index', 'slc_visit', 'v_id', 'id');
+ $db->addJoin('inner', 'slc_visit', 'slc_client', 'c_id', 'id');
+ $db->addJoin('inner', 'slc_visit_issue_index', 'slc_issue', 'i_id', 'id');
+ $db->addJoin('inner', 'slc_issue', 'slc_problem', 'problem_id', 'id');
+ $db->addWhere('slc_visit.initial_date', $start_date, '>=');
+ $db->addWhere('slc_visit.initial_date', $end_date, '<', 'AND');
+ $results = $db->select();
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ // return an "empty" message if $results is empty
+ if (count($results) == 0) {
+ $html = "There are no records for that time period.";
+ return $html;
+ }
+
+ $html = "";
+
+ $theMatrix = array();
+ $problems = array();
+ $years = array();
+
+ /*
+ * For each row where the type is Conditions or Landlord-Tenant, change
+ * the type to a generic Landlord-Tenant problem.
+ */
+ foreach ($results as $key=>$r) {
+ if (isset($r['description']) && ($r['description'] == 'Conditions')) {
+ $results[$key]['description'] = 'Landlord-Tenant';
+ $results[$key]['tree'] = '';
+ }
+ if (isset($r['tree']) && ($r['tree'] == 'Landlord-Tenant -> ' || $r['tree'] == 'Landlord-Tenant -> Condition -> ')) {
+ $results[$key]['description'] = 'Landlord-Tenant';
+ $results[$key]['tree'] = '';
+ }
+ }
+
+ // Replace the 'FR' with 'Freshman', 'SO' with 'Sophomore', and so on
+ foreach ($results as $key=>$val) {
+ switch ($val['classification']) {
+ case 'FR':
+ $results[$key]['classification'] = 'Freshman';
+ break;
+ case 'SO':
+ $results[$key]['classification'] = 'Sophomore';
+ break;
+ case 'JR':
+ $results[$key]['classification'] = 'Junior';
+ break;
+ case 'SR':
+ $results[$key]['classification'] = 'Senior';
+ break;
+ case '':
+ $results[$key]['classification'] = 'Other';
+ break;
+ default:
+ break;
+ }
+ }
+
+ foreach( $results as $r ) {
+ if ( !in_array($r['classification'], $years) ) {
+ $years[] = $r['classification'];
+ }
+ }
+
+ // Sort the 'years' array
+ $classes = array('Freshman', 'Sophomore', 'Junior', 'Senior', 'Other');
+ $tempArray = array_intersect($classes, $years);
+ $years = array_unique(array_merge($tempArray, $years));
+
+ foreach( $results as $r ) {
+
+ $description = isset($r['description']) && isset($r['tree']) ? $r['tree'].' '.$r['description'] : "not specified";
+ $year = $r['classification'];
+
+ if ( !in_array($description, $problems) )
+ $problems[] = $description;
+
+ if ( isset($theMatrix[$description]) ) {
+ $theMatrix[$description][$year]++;
+ } else {
+ $theMatrix[$description] = array();
+ foreach ($years as $tempyear) {
+ $theMatrix[$description][$tempyear] = 0;
+ }
+
+ $theMatrix[$description][$year] = 1;
+ }
+ }
+
+ $bgcolor = array(0=>"255,255,255",1=>"255,236,139");
+ $rc = 0;
+
+ $html .= "";
+ $html .= "Problem Type | ";
+
+ // Total the columns
+ $totals = array_flip($years);
+ foreach ($totals as $key=>$val) {
+ $totals[$key] = 0;
+ }
+
+ foreach ( $years as $year ) {
+ $html .= " ".$year." | ";
+ }
+ $html .= "
";
+ foreach ( $problems as $description ) {
+ $html .= "";
+ $html .= "".$description." | ";
+ $prevCount = 0;
+ foreach ( array_keys($theMatrix[$description]) as $year ) {
+ $html .= "";
+ $html .= ($theMatrix[$description][$year] != 0) ? $theMatrix[$description][$year] : '0';
+ $html .= " | ";
+
+ if ($theMatrix[$description][$year] != 0) {
+ $totals[$year] += $theMatrix[$description][$year];
+ }
+ }
+
+ $html .= "
";
+ $rc = !$rc;
+ }
+ $html .= "Totals | ";
+ foreach ($totals as $total) {
+ $html .= "".$total." | ";
+ }
+ $html .= "
";
+ $html .= "
";
+
+ return $html;
+ }
+
+ /**
+ * This method builds the Appointment Statistics report.
+ */
+ private function REPORTfollowupappts() {
+ $initialVisits = 0;
+ $clients = 0;
+ $issues = 0;
+ $followups = 0;
+
+ // Get date range from user
+ $start_date = strtotime($_REQUEST['start_date']);
+ $end_date = strtotime($_REQUEST['end_date']) + 86400; // +1 day to make date range inclusive
+
+ // Get the array of all visits whose initial visit happened in the time period. Equivalent to this query:
+ // SELECT DISTINCT(id) FROM slc_visit WHERE initial_date >= $start_date AND initial_date < $end_date;
+ $db = new PHPWS_DB('slc_visit');
+ $db->addColumn('id', null, null, null, true);
+ $db->addWhere('initial_date', $start_date, '>=');
+ $db->addwhere('initial_date', $end_date, '<', 'AND');
+ $visitIds = $db->select('col');
+
+ // Get # of initial visits. Equivalent to this query:
+ // SELECT COUNT(DISTINCT(v_id)) FROM slc_visit_issue_index
+ // WHERE v_id IN $visitIds;
+ $db = new PHPWS_DB('slc_visit_issue_index');
+ $db->addColumn('v_id', null, null, true, true);
+ $db->addWhere('v_id', $visitIds, 'IN', 'AND');
+ $initialVisits = $db->select('one');
+
+ // Get the array of different 'counts' greater than 1. Equivalent to this query:
+ // SELECT DISTINCT(counter) FROM slc_visit_issue_index WHERE counter>'1' ORDER BY counter DESC;
+ $db->reset();
+ $db->addColumn('counter', null, null, null, true);
+ $db->addWhere('counter', '1', '>');
+ $db->addOrder('counter desc');
+ $counters = $db->select('col');
+
+ //TODO: Make followups only count if they occured during the time period.
+ // As of 05/20/2013 this is impossible due to the structure of the DB. We need to track when each followup occured.
+ // For now we just count all followups for visits whose initial visit took place within the time period.
+
+ // Calculate the number of followup visits.
+ $visits = array();
+ $db = new PHPWS_DB('slc_visit_issue_index');
+ $db->addColumn('v_id', null, null, null, true);
+ foreach ($counters as $count) {
+ $db->addWhere('v_id', $visitIds, 'IN');
+
+ // Make sure you don't count visits with multiple issues if they've already been counted.
+ if (!empty($visits)) {
+ $db->addWhere('v_id', $visits, 'NOT IN', 'AND');
+ }
+
+ $db->addWhere('counter', $count, '=', 'AND');
+ $result = $db->select('col');
+ $visits = $visits + $result;
+ $followups += ($count-1) * count($result);
+ $db->resetWhere();
+ }
+
+ // Get # of clients. Equivalent to this query:
+ // SELECT COUNT(DISTINCT(id)) FROM slc_client
+ // WHERE first_visit >= $start_date AND first_visit < $end_date;
+ $db = new PHPWS_DB('slc_client');
+ $db->addColumn('id', null, null, true, true);
+ $db->addWhere('first_visit', $start_date, '>=');
+ $db->addWhere('first_visit', $end_date, '<', 'AND');
+ $clients = $db->select('one');
+
+ // Get # of issues. Equivalent to this query:
+ // SELECT COUNT(DISTINCT(id)) FROM slc_issue
+ // JOIN slc_visit_issue_index ON slc_issue.id = slc_visit_issue_index.i_id
+ // WHERE slc_visit_issue_index.v_id IN $visitIds;
+ $db = new PHPWS_DB('slc_issue');
+ $db->addColumn('id', null, null, true, true);
+ $db->addTable('slc_visit_issue_index', 'svii');
+ $db->addWhere('slc_issue.id', 'svii.i_id');
+ $db->addWhere('svii.v_id', $visitIds, 'IN', 'AND');
+ $issues = $db->select('one');
+
+ $bgcolor = array(0=>"255,255,255",1=>"255,236,139");
+ $rc = 0;
+
+ $html = "";
+ $html .= "Category | Statistic |
";
+ $html .= "Total Clients | ".$clients." |
";
+ $html .= "Total Issues | ".$issues." |
";
+ $html .= "Total Initial Visits | ".$initialVisits." |
";
+ $html .= "Total Followups | ".$followups." |
";
+ if ($clients == 0) { // If $clients == 0, then all the statistics will be 0
+ $html .= "Issues per Visit (w/o Followups) | 0 |
";
+ $html .= "Visits per Client (w/o Followups) | 0 |
";
+ $html .= "Visits per Client (with Followups) | 0 |
";
+ $html .= "Followups per Issue | 0 |
";
+ $html .= "Followups per Visit | 0 |
";
+ } else {
+ $html .= "Issues per Visit (w/o Followups) | " . round($issues / $initialVisits, 2) . " |
";
+ $html .= "Visits per Client (w/o Followups) | " . round($initialVisits / $clients, 2) . " |
";
+ $html .= "Visits per Client (with Followups) | " . round(($initialVisits + $followups) / $clients, 2) . " |
";
+ $html .= "Followups per Issue | " . round($followups / $issues, 2) . " |
";
+ $html .= "Followups per Visit | " . round($followups / $initialVisits, 2) . " |
";
+ }
+ $html .= "
";
+
+ return $html;
+ }
+
+
+ private function REPORTtypeofcondition() {
+ // Get date range from user
+ $start_date = strtotime($_REQUEST['start_date']);
+ $end_date = strtotime($_REQUEST['end_date']) + 86400; // +1 day to make date range inclusive
+
+ $db = new PHPWS_DB('slc_problem');
+ $db->addColumn('slc_problem.description', NULL, 'descript');
+ $db->addJoin('inner', 'slc_problem', 'slc_issue', 'id', 'problem_id');
+ $db->addJoin('inner', 'slc_issue', 'slc_visit_issue_index', 'id', 'i_id');
+ $db->addJoin('inner', 'slc_visit_issue_index', 'slc_visit', 'v_id', 'id');
+ $db->addWhere('slc_problem.type', 'Conditions', 'LIKE');
+ $db->addWhere('slc_visit.initial_date', $start_date, '>=', 'AND');
+ $db->addWhere('slc_visit.initial_date', $end_date, '<', 'AND');
+ $results = $db->select();
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ // return an "empty" message if $results is empty
+ if (count($results) == 0) {
+ $html = "There are no records for that time period.";
+ return $html;
+ }
+
+ $conditions = array();
+
+ foreach ($results as $r) {
+ if ( !array_key_exists($r['descript'], $conditions) )
+ $conditions[$r['descript']] = 1;
+ else
+ $conditions[$r['descript']]++;
+ }
+
+ $bgcolor = array(0=>"255,255,255",1=>"255,236,139");
+ $rc = 1;
+
+ $html = "";
+ $html .= "Category | Statistic |
";
+
+ foreach($conditions as $k=>$c)
+ $html .= "".$k." | ".$c." |
";
+
+ $html .= "
";
+
+ return $html;
+ }
+
+
+ private function REPORTtypeofreferral() {
+ // Get date range from user
+ $start_date = strtotime($_REQUEST['start_date']);
+ $end_date = strtotime($_REQUEST['end_date']) + 86400; // +1 day to make date range inclusive
+
+ $db = new PHPWS_DB('slc_referral_type');
+ $db->addColumn('name');
+ $db->addWhere('id', 'slc_client.referral');
+ $db->addWhere('slc_client.first_visit', $start_date, '>=', 'AND');
+ $db->addWhere('slc_client.first_visit', $end_date, '<', 'AND');
+ $results = $db->select();
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ // return an "empty" message if $results is empty
+ if (count($results) == 0) {
+ $html = "There are no records for that time period.";
+ return $html;
+ }
+
+ $referrals = array();
+
+ foreach ($results as $r) {
+ if ( $r['name'] != '')
+ if ( !array_key_exists($r['name'], $referrals) )
+ $referrals[$r['name']] = 1;
+ else
+ $referrals[$r['name']]++;
+ }
+
+ $bgcolor = array(0=>"255,255,255",1=>"255,236,139");
+ $rc = 1;
+
+ $html = "";
+ $html .= "Referral Type | Statistic |
";
+
+ foreach($referrals as $k=>$c)
+ $html .= "".$k." | ".$c." |
";
+
+ $html .= "
";
+
+ return $html;
+ }
+
+
+ private function REPORTlawbyagency() {
+ // Get date range from user
+ $start_date = strtotime($_REQUEST['start_date']);
+ $end_date = strtotime($_REQUEST['end_date']) + 86400; // +1 day to make date range inclusive
+
+ $db = new PHPWS_DB('slc_problem');
+ $db->addColumn('slc_problem.description', NULL, 'agency');
+ $db->addJoin('inner', 'slc_problem', 'slc_issue', 'id', 'problem_id');
+ $db->addJoin('inner', 'slc_issue', 'slc_visit_issue_index', 'id', 'i_id');
+ $db->addJoin('inner', 'slc_visit_issue_index', 'slc_visit', 'v_id', 'id');
+ $db->addWhere('slc_problem.type', 'Law Enforcement Agency', 'LIKE');
+ $db->addWhere('slc_visit.initial_date', $start_date, '>=', 'AND');
+ $db->addWhere('slc_visit.initial_date', $end_date, '<', 'AND');
+ $results = $db->select();
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ // return an "empty" message if $results is empty
+ if (count($results) == 0) {
+ $html = "There are no records for that time period.";
+ return $html;
+ }
+
+ $agencies = array();
+
+ foreach ($results as $r) {
+ if ( !array_key_exists($r['agency'], $agencies) )
+ $agencies[$r['agency']] = 1;
+ else
+ $agencies[$r['agency']]++;
+ }
+
+ $bgcolor = array(0=>"255,255,255",1=>"255,236,139");
+ $rc = 1;
+
+ $html = "";
+ $html .= "Agency | Statistic |
";
+
+ foreach($agencies as $k=>$c)
+ $html .= "".$k." | ".$c." |
";
+
+ $html .= "
";
+
+ return $html;
+ }
+
+}
diff --git a/class/ajax/GETReportBox.php b/class/ajax/GETReportBox.php
new file mode 100644
index 0000000..d44fe51
--- /dev/null
+++ b/class/ajax/GETReportBox.php
@@ -0,0 +1,32 @@
+ $v ) { // types
+ $rTypes[] = array("VALUE" => $r, "NAME"=>$v);
+ }
+
+ $reportPicker = PHPWS_Template::process(array("reports"=>$rTypes), 'slc', 'ReportPicker.tpl');
+
+ $this->addResult("report_picker", $reportPicker);
+ }
+}
+?>
diff --git a/class/ajax/GETReporthalfway.php b/class/ajax/GETReporthalfway.php
new file mode 100644
index 0000000..d33bc62
--- /dev/null
+++ b/class/ajax/GETReporthalfway.php
@@ -0,0 +1,209 @@
+addResult("msg", "No Report Type Supplied");
+ // throw new ReportTypeNotSuppliedException();
+ return;
+ }
+
+ $reportHTML = "";
+
+ $func = 'REPORT'.$_REQUEST['report_type'];
+
+ if ( method_exists("GETReport", $func) )
+ $reportHTML .= call_user_func(array("GETReport", $func));
+ else
+ $reportHTML .= "The selected report type (".$_REQUEST['report_type'].") is not yet implemented in this version";
+
+ $this->addResult('report_html', $reportHTML);
+ }
+
+ function REPORTstudentsseen() {
+
+ $query = "SELECT ";
+ $query .= "(SELECT COUNT(DISTINCT id) FROM slc_visit) AS visits, ";
+ $query .= "(SELECT COUNT(DISTINCT id) FROM slc_client) AS clients, ";
+ $query .= "(SELECT COUNT(DISTINCT id) FROM slc_issue) AS issues, ";
+ $query .= "(SELECT SUM(counter) FROM slc_visit_issue_index) AS followups ";
+
+ $db = new PHPWS_DB();
+ //$db->setTestMode();
+ $results = $db->select(null, $query);
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ $results = $results[0]; // since it's a count, should always return a number
+ $visits = $results['visits'];
+ $clients = $results['clients'];
+ $issues = $results['issues'];
+ $followups = $results['followups'] - $issues; // Every issue has at least one visit, so remove initial
+
+ $bgcolor = array(0=>"#FFFFFF",1=>"#FFEC8B");
+ $r = 0;
+
+ $html = "";
+ $html .= "";
+ $html .= "Situation | Record |
";
+ $html .= "Total Visits | ".$visits." |
"; $r = !$r;
+ $html .= "Total Clients | ".$clients." |
"; $r = !$r;
+ $html .= "Total Issues | ".$issues." |
"; $r = !$r;
+ $html .= "Visits per Client | ".(round($visits/$clients,2))." |
"; $r = !$r;
+ $html .= "Issues per Visit | ".(round($issues/$visits,2))." |
"; $r = !$r;
+ $html .= "Followups per Issue | ".(round($followups/$issues, 2))." |
"; $r = !$r;
+ $html .= "
";
+
+ return $html;
+ }
+
+ private function REPORTintakebyproblemtype() {
+ $query = "SELECT COUNT(DISTINCT i.id) as count, p.description FROM slc_issue i, slc_problem p WHERE i.problem_id = p.id GROUP BY problem_id";
+
+ $db = new PHPWS_DB();
+ //$db->setTestMode();
+ $results = $db->select(null, $query);
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ $html = "";
+ $html .= "";
+ $html .= "Situation | Record |
";
+ $bgcolor = array(0=>"#FFFFFF",1=>"#FFEC8B");
+ $rc = 0;
+
+ foreach( $results as $r ) {
+ $count = $r['count'];
+ $type = $r['description'];
+
+ $html .= "".$type." | ".$count." |
";
+ $rc = !$rc;
+ }
+
+ $html .= "
";
+
+ return $html;
+ }
+
+ //' (SELECT COUNT(DISTINCT id) FROM landlord) AS landlords, '.
+ //' (SELECT COUNT(DISTINCT id) FROM issue WHERE landlord_id IS NOT NULL) AS issues";
+
+ private function REPORTlandlordtenant() {
+ $landlords = "SELECT * FROM slc_landlord";
+ $db = new PHPWS_DB();
+ $landlords = $db->select(null, $landlords);
+ $landlordnames = array();
+ foreach( $landlords as $landlord )
+ $landlordnames[] = $landlord['name'];
+ $landlordnames[] = "not specified"; // Create a "NULL" row
+
+ $issues = "SELECT * FROM slc_problem WHERE tree LIKE '%Landlord-Tenant%' OR description LIKE 'Conditions' OR description LIKE 'Landlord-Tenant' "; // Covers generic landlord-tenant, too
+ $db = new PHPWS_DB();
+ $issues = $db->select(null, $issues);
+ $issuenames = array();
+ foreach( $issues as $issue )
+ $issuenames[] = $issue['description'];
+
+
+ // Get the issues listed ( all others 0 )
+ $query = 'SELECT p.description, l.name '.
+ ' FROM slc_issue i '.
+ ' LEFT JOIN slc_problem p ON i.problem_id = p.id '.
+ ' LEFT JOIN slc_landlord l ON i.landlord_id = l.id ';
+
+ $db = new PHPWS_DB();
+ //$db->setTestMode();
+ $results = $db->select(null, $query);
+
+ if(PHPWS_Error::logIfError($results)){
+ throw new DatabaseException();
+ }
+
+ $theMatrix = $landlordnames;
+ foreach($landlordnames as $lname) {
+ $theMatrix[$lname] = $issuenames;
+ foreach($issuenames as $iname)
+ $theMatrix[$lname][$iname] = 0; // Populate with 0s
+ }
+
+
+ foreach( $results as $r ) {
+ //if(!isset($r['name'])){
+ // continue;
+ //}
+
+ $name = isset($r['name']) ? $r['name'] : "not specified";
+ $description = $r['description'];
+
+ $theMatrix[$name][$description]++; // increment that value
+ }
+
+
+ $html = "";
+ $html .= "";
+ $html .= "