Skip to content

Vitals audit - based on Shad's PR #127

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0e3e1bb
Update Student Vitals field to be audit for use in Chart
Feb 8, 2018
579b143
Added reason for audit to Student Docs
Feb 8, 2018
7d512b0
Merge branch 'master' into vitals-audit
mmarum-sugarcrm Feb 9, 2018
1301a5d
Dashlet to retrieve count of days in vitals status
Apr 26, 2018
7daa957
Merge branch 'vitals-audit' of github.com:ShadMickelberry/school into…
Apr 26, 2018
9cab591
Merge branch 'master' of https://github.com/sugarcrm/school into vita…
Apr 26, 2018
de18329
Merge branch 'master' into vitals-audit
mmarum-sugarcrm May 4, 2018
48a6836
Merge branch 'master' into vitals-audit
mmarum-sugarcrm May 29, 2018
4d2e791
Fix config dropdown width for dynamic team options.
Feb 20, 2019
64ee136
Add missing language file
Feb 20, 2019
9e36986
Code standards for class naming. Modify joins on SugarQuery
Feb 20, 2019
2103e3d
Update documentation for Student Health Tracking. Add Api help docume…
Feb 22, 2019
d293787
Change teams variables and usage to supergroups.
Feb 22, 2019
f6e98ff
Update StudentHealthTracking.md
ShadMickelberry Feb 22, 2019
6cc0367
Resolve conflicts with upstream
ShadMickelberry Feb 22, 2019
d171d19
Resolve conflicts with upstream
ShadMickelberry Feb 22, 2019
f02a633
Merge branch 'master' into vitals-audit
mmarum-sugarcrm Apr 10, 2019
ec83924
Add support for Sugar 9.0 tests
mmarum-sugarcrm Apr 11, 2019
fa18074
Simplify the vitals auditing feature
mmarum-sugarcrm Apr 11, 2019
f41025f
Update API docs
mmarum-sugarcrm Apr 12, 2019
734cfb9
rebase
mmarum-sugarcrm Apr 12, 2019
a56d204
Merge branch 'master' into vitals-audit
mmarum-sugarcrm Apr 12, 2019
387e9d9
Merge branch 'master' into vitals-audit
mmarum-sugarcrm Jul 3, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion docs/StudentHealthTracking.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,14 @@ the Death Information panel will appear so you can also input the Cause of Death
sent.

View the **Cause of Death Report** and the **Student Health Report** by navigating to the Reports module and clicking
on the appropriate report title.
on the appropriate report title.

## Common Student Injuries dashlet
A new dashlet is available to track the number of times Students are injured over time. This dashlet leverages
the Contacts Audit table to populate a pie chart summarizing the number of times Students for in a given Super Group (or all Super Groups) enter a non-active Vital Status.

This dashlet displays use of the Sucrose charts in a custom dashlet and is available in Home, List Views, and Record Views.

There is also an accompanying API endpoint for retrieve the data from the Student records and shows use of Doctrine QueryBuilder in a complex parameterized query that can't be created using SugarQuery APIs. For more information on the endpoint see <instnace>/rest/v11/help.

The pull request for the Student vitals dashlet can be viewed in [#27](https://github.com/sugarcrm/school/pull/27).
2 changes: 1 addition & 1 deletion package/pack.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@
'default_value' => 'active',
'date_modified' => '2018-02-01 21:32:16',
'deleted' => '0',
'audited' => '0',
'audited' => '1',
'mass_update' => '1',
'duplicate_merge' => '1',
'reportable' => '1',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

$app_strings['LBL_STUDENT_VITAL_CHART_DESC'] = 'Pie Chart shows most common student body problems over time';
$app_strings['LBL_STUDENT_VITAL_CHART'] = 'Student Body Problems';
$app_strings['LBL_VITALS_DASHLET_SELECT_TEAM'] = 'Select Super Group to view data on';
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

$app_list_strings['problems_list'] = array (
'injured' => 'Injuries',
'comatose' => 'Comas',
'deceased' => 'Deaths',
);
83 changes: 83 additions & 0 deletions package/src/custom/clients/base/api/StudentVitalsApi.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php


class StudentVitalsApi extends SugarApi
{
public function registerApiRest()
{
return array(
'getStudentVitalData' => array(
'reqType' => 'GET',
'noLoginRequired' => false,
'path' => array('professorM', 'getStudentVitalData', '?'),
'pathVars' => array('', '', 'supergroup'),
'method' => 'getStudentVitalData',
'shortHelp' => 'API End point to retrieve data for vitals dashlet',
'longHelp' => 'custom/include/api/help/student_vitals_api_help.html',
),
);
}

/**
* API Endpoint for student vitals chart
* @param $api
* @param $args
*
* @return false|string
* @throws SugarQueryException
*/
public function getStudentVitalData($api, $args)
{

global $app_list_strings;
$supergroup = $args['supergroup'];
$helper = new \Sugarcrm\Sugarcrm\custom\inc\ProfessorM\StudentVitalHelper();
$status_data = $helper->countStudentIncidents($supergroup);


// Sort if we have an array
if (is_array($status_data)) {
arsort($status_data);
}
$chart_data = array();

$seriesIdx = 1;
foreach ($status_data as $key => $value) {
if (!empty($key)) {

$app_list_strings['problems_list'][$key];

$chart_data[] = array(
"key" => $app_list_strings['problems_list'][$key],
"value" => $value,
"total" => $value,
"seriesIndex" => $seriesIdx++
);
}

}

$title = '';
if($supergroup != 'all') {
$sg = BeanFactory::retrieveBean("Accounts", $supergroup);
$title = "$sg->name Student Problems";
} else {
$title = "All Student Problems";
}

$data = array(
"properties" => array(
"title" => $title,
"seriesName" => "Problems"
),
"data"=> $chart_data


);


return $data;

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<div class="student-vital-chart">
<div class="sc-chart" data-content="chart">
<svg id="{{cid}}"></svg>
</div>
<div class="block-footer hide" data-content="nodata">{{str "LBL_NO_DATA_AVAILABLE"}}</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Your installation or use of this SugarCRM file is subject to the applicable
* terms available at
* http://support.sugarcrm.com/Resources/Master_Subscription_Agreements/.
* If you do not agree to all of the applicable terms or do not have the
* authority to bind the entity as an authorized representative, then do not
* install or use this SugarCRM file.
*
* Copyright (C) SugarCRM Inc. All rights reserved.
*/
({
plugins: ['Dashlet', 'Chart'],
className: 'student-vital-chart',
chartCollection: null,
hasData: false,
total: 0,

/**
* @inheritdoc
*/
initialize: function(options) {
this._super('initialize', [options]);

this.chart = sucrose.charts.pieChart()
.donut(true)
.donutLabelsOutside(true)
.donutRatio(0.25)
.hole(false)
.showTitle(true)
.tooltips(true)
.showLegend(true)
.colorData('class')
.tooltipContent(_.bind(function(eo, properties) {

var value = parseInt(this.chart.getValue()(eo), 10);
var total = parseInt(properties.total, 10);
(total == 0) ? total = 1 : '';
var percentage = value/total * 100;
return '<h3>' + this.chart.fmtKey()(eo) + '</h3>' +
'<p>' + value + '</p>' +
'<p>' + percentage.toFixed(2) + '%</p>';
}, this))
.strings({
noData: app.lang.get('No Problems')
});
},

/**
* Override to set options for supergroup selector in config dynamically
*/
initDashlet: function() {
if (this.meta.config) {

var supergroup_value = this.meta.vitals_dashlet_supergroup ? this.meta.vitals_dashlet_supergroup : 'all';
var accounts = app.data.createBeanCollection('Accounts');
var supergroups = [];
supergroups.push({id: 'all', text:'All'})
accounts.fetch({
success: function() {
accounts.comparator = 'name';
accounts.sort({silent: true});
_.each(accounts.models, function(account){
supergroups.push({id: account.id, text: account.attributes.name});
});

$('[name="vitals_dashlet_supergroup"]').html('').select2({data: supergroups, width: '100%'});
$('[name="vitals_dashlet_supergroup"]').val(supergroup_value).trigger('change');
}
})
}

this._super('initDashlet');
},


/**
* Generic method to render chart with check for visibility and data.
* Called by _renderHtml and loadData.
*/
renderChart: function() {
var self = this;
if (!self.isChartReady()) {
return;
}

d3sugar.select(this.el).select('svg#' + this.cid)
.datum(self.chartCollection)
.transition().duration(500)
.call(self.chart);

this.chart_loaded = _.isFunction(this.chart.update);
this.displayNoData(!this.chart_loaded);

},

/**
* @inheritdoc
*/
loadData: function(options) {

if(this.meta.config) {

return;
}
var self = this;
var supergroup_value = this.meta.vitals_dashlet_supergroup ? this.meta.vitals_dashlet_supergroup : 'all';
url = app.api.buildURL('professorM/getStudentVitalData/' + supergroup_value);
this.hasData = false;
app.api.call('GET', url, null, {
success: function(data) {
self.hasData = true;
self.evaluateResponse(data);
self.render();
},
complete: options ? options.complete : null
});

},


evaluateResponse: function(data) {

this.total = 1;
this.hasData = true;
this.chartCollection = data;

},


})  
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

$viewdefs['base']['view']['student-vital-chart'] = array(
'dashlets' => array(
array(
'label' => 'LBL_STUDENT_VITAL_CHART',
'description' => 'LBL_STUDENT_VITAL_CHART_DESC',
'config' => array(
'supergroup' => 'all',
),
'preview' => array(
),
'filter' => array(
'view' => array(
'records',
'record'
)
),

),

),
'panels' => array(
array(
'name' => 'panel_body',
'columns' => 2,
'labelsOnTop' => true,
'placeholders' => true,
'fields' => array(

array(
'name' => 'vitals_dashlet_supergroup',
'label' => 'LBL_VITALS_DASHLET_SELECT_TEAM',
'type' => 'enum',
'span' => 6,
'options' => array('all' => 'All'),
),
),
),
),
);
72 changes: 72 additions & 0 deletions package/src/custom/include/ProfessorM/StudentVitalHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php


namespace Sugarcrm\Sugarcrm\custom\inc\ProfessorM;


/**
* Class StudentVitalHelper
*
* Helper to retrieve data for student vitals dashboard
*
* @package Sugarcrm\ProfessorM\Helpers
*/
class StudentVitalHelper
{


/**
* Called by API to count changes in health status affecting Contacts (Students)
* Also an example of using Doctrine QueryBuilder to query contacts_audit table
* @param $supergroup
*
* @return mixed
* @throws \SugarQueryException
*/
public function countStudentIncidents($supergroup)
{

$pie = array();
$queryResults = $this->getVitalChangeData($supergroup);

foreach ($queryResults as $row) {
$pie[$row['problem']] = $row['count'];
}

return $pie;
}


/**
* Query to retrieve student vitals transactions for given supergroup
* @param $supergroup
*
* @return array
* @throws \SugarQueryException
*/
public function getVitalChangeData($supergroup = 'all')
{
global $app_list_strings;
$results = array();
$trackedStatuses = array_keys($app_list_strings['problems_list']);

foreach($trackedStatuses as $status){
$qb = $conn = $GLOBALS['db']->getConnection()->createQueryBuilder();
$qb->from("contacts");
$qb->innerJoin('contacts', 'contacts_audit', 'ca', "contacts.id=ca.parent_id");
if ($supergroup != 'all') {
$qb ->join('contacts', 'accounts_contacts', 'ac', "contacts.id = ac.contact_id AND ac.account_id = :sg");
$qb->setParameter('sg', $supergroup);
}
$qb->select("COUNT(*) AS count, ca.after_value_string AS problem");
$qb->andWhere("contacts.deleted = 0");
$qb->andWhere("ca.field_name = 'vitals_c'");
$qb->andWhere("ca.after_value_string = :status");
$qb->setParameter('status', $status);
$results = array_merge($results, $qb->execute()->fetchAll());
}
return $results;
}


}
Loading