dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #32701
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 16674: tracker capture - report for overdue events
------------------------------------------------------------
revno: 16674
committer: Abyot Asalefew Gizaw <abyota@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2014-09-09 15:26:15 +0200
message:
tracker capture - report for overdue events
modified:
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/overdue-events-controller.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/overdue-events.html
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/upcoming-events-controller.js
--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk
Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/overdue-events-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/overdue-events-controller.js 2014-08-27 12:55:29 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/overdue-events-controller.js 2014-09-09 13:26:15 +0000
@@ -1,6 +1,216 @@
trackerCapture.controller('OverdueEventsController',
- function(TranslationService) {
-
- TranslationService.translate();
-
+ function($scope,
+ $modal,
+ $location,
+ orderByFilter,
+ DateUtils,
+ EventUtils,
+ TEIService,
+ TEIGridService,
+ TranslationService,
+ AttributesFactory,
+ ProgramFactory,
+ DHIS2EventFactory,
+ storage) {
+
+ TranslationService.translate();
+
+ $scope.today = DateUtils.format(moment());
+
+ $scope.ouModes = [{name: 'SELECTED'}, {name: 'CHILDREN'}, {name: 'DESCENDANTS'}, {name: 'ACCESSIBLE'}];
+ $scope.selectedOuMode = $scope.ouModes[0];
+ $scope.report = {};
+ $scope.displayMode = {};
+
+ //watch for selection of org unit from tree
+ $scope.$watch('selectedOrgUnit', function() {
+ if( angular.isObject($scope.selectedOrgUnit)){
+ storage.set('SELECTED_OU', $scope.selectedOrgUnit);
+ $scope.loadPrograms($scope.selectedOrgUnit);
+ }
+ });
+
+ //load programs associated with the selected org unit.
+ $scope.loadPrograms = function(orgUnit) {
+ $scope.selectedOrgUnit = orgUnit;
+ if (angular.isObject($scope.selectedOrgUnit)){
+ ProgramFactory.getAll().then(function(programs){
+ $scope.programs = programs;
+ if($scope.programs.length === 1){
+ $scope.selectedProgram = $scope.programs[0];
+ }
+ });
+ }
+ };
+
+ //watch for selection of program
+ $scope.$watch('selectedProgram', function() {
+ $scope.reportFinished = false;
+ $scope.reportStarted = false;
+ });
+
+ $scope.generateReport = function(program, report, ouMode){
+
+ $scope.selectedProgram = program;
+ $scope.report = report;
+ $scope.selectedOuMode = ouMode;
+
+ //check for form validity
+ $scope.outerForm.submitted = true;
+ if( $scope.outerForm.$invalid || !$scope.selectedProgram){
+ return false;
+ }
+
+ $scope.reportFinished = false;
+ $scope.reportStarted = true;
+ $scope.programStages = [];
+ $scope.filterTypes = {};
+ $scope.filterText = {};
+
+ angular.forEach($scope.selectedProgram.programStages, function(stage){
+ $scope.programStages[stage.id] = stage;
+ });
+
+ AttributesFactory.getByProgram($scope.selectedProgram).then(function(atts){
+ $scope.gridColumns = TEIGridService.generateGridColumns(atts, $scope.selectedOuMode.name);
+
+ $scope.gridColumns.push({name: 'event_name', id: 'event_name', type: 'string', displayInListNoProgram: false, showFilter: false, show: true});
+ $scope.filterTypes['event_name'] = 'string';
+
+ $scope.gridColumns.push({name: 'due_date', id: 'due_date', type: 'date', displayInListNoProgram: false, showFilter: false, show: true});
+ $scope.filterTypes['due_date'] = 'date';
+ $scope.filterText['due_date']= {};
+ });
+
+ //fetch TEIs for the selected program and orgunit/mode
+ TEIService.search($scope.selectedOrgUnit.id,
+ $scope.selectedOuMode.name,
+ null,
+ 'program=' + $scope.selectedProgram.id,
+ null,
+ $scope.pager,
+ false).then(function(data){
+
+ //process tei grid
+ var teis = TEIGridService.format(data,true);
+ $scope.teiList = [];
+ DHIS2EventFactory.getByOrgUnitAndProgram($scope.selectedOrgUnit.id, $scope.selectedOuMode.name, $scope.selectedProgram.id, null, null).then(function(eventList){
+ $scope.dhis2Events = [];
+ angular.forEach(eventList, function(ev){
+ if(ev.dueDate){
+ ev.dueDate = DateUtils.format(ev.dueDate);
+
+ if( ev.trackedEntityInstance &&
+ !ev.eventDate &&
+ ev.dueDate < $scope.today){
+
+ ev.name = $scope.programStages[ev.programStage].name;
+ ev.programName = $scope.selectedProgram.name;
+ ev.statusColor = EventUtils.getEventStatusColor(ev);
+ ev.dueDate = DateUtils.format(ev.dueDate);
+
+ if($scope.dhis2Events[ev.trackedEntityInstance]){
+ if(teis.rows[ev.trackedEntityInstance]){
+ $scope.teiList.push(teis.rows[ev.trackedEntityInstance]);
+ delete teis.rows[ev.trackedEntityInstance];
+ }
+ $scope.dhis2Events[ev.trackedEntityInstance].push(ev);
+ }
+ else{
+ if(teis.rows[ev.trackedEntityInstance]){
+ $scope.teiList.push(teis.rows[ev.trackedEntityInstance]);
+ delete teis.rows[ev.trackedEntityInstance];
+ }
+ $scope.dhis2Events[ev.trackedEntityInstance] = [ev];
+ }
+ ev = EventUtils.setEventOrgUnitName(ev);
+ }
+ }
+ });
+
+ //incase a TEI happens to have more than one overdue, sort using duedate
+ for(var tei in $scope.dhis2Events){
+ $scope.dhis2Events[tei] = orderByFilter($scope.dhis2Events[tei], '-dueDate');
+ $scope.dhis2Events[tei].reverse();
+ }
+
+ //make upcoming event name and its due date part of the grid column
+ for(var i=0; i<$scope.teiList.length; i++){
+ $scope.teiList[i].event_name = $scope.dhis2Events[$scope.teiList[i].id][0].name;
+ $scope.teiList[i].due_date = $scope.dhis2Events[$scope.teiList[i].id][0].dueDate;
+ $scope.teiList[i].followup = $scope.dhis2Events[$scope.teiList[i].id][0].followup;
+ }
+
+ $scope.reportFinished = true;
+ $scope.reportStarted = false;
+ });
+ });
+ };
+
+ $scope.showHideColumns = function(){
+
+ $scope.hiddenGridColumns = 0;
+
+ angular.forEach($scope.gridColumns, function(gridColumn){
+ if(!gridColumn.show){
+ $scope.hiddenGridColumns++;
+ }
+ });
+
+ var modalInstance = $modal.open({
+ templateUrl: 'views/column-modal.html',
+ controller: 'ColumnDisplayController',
+ resolve: {
+ gridColumns: function () {
+ return $scope.gridColumns;
+ },
+ hiddenGridColumns: function(){
+ return $scope.hiddenGridColumns;
+ }
+ }
+ });
+
+ modalInstance.result.then(function (gridColumns) {
+ $scope.gridColumns = gridColumns;
+ }, function () {
+ });
+ };
+
+ $scope.sortTEIGrid = function(gridHeader){
+ if ($scope.sortHeader === gridHeader.id){
+ $scope.reverse = !$scope.reverse;
+ return;
+ }
+ $scope.sortHeader = gridHeader.id;
+ $scope.reverse = false;
+ };
+
+ $scope.searchInGrid = function(gridColumn){
+
+ $scope.currentFilter = gridColumn;
+
+ for(var i=0; i<$scope.gridColumns.length; i++){
+
+ //toggle the selected grid column's filter
+ if($scope.gridColumns[i].id === gridColumn.id){
+ $scope.gridColumns[i].showFilter = !$scope.gridColumns[i].showFilter;
+ }
+ else{
+ $scope.gridColumns[i].showFilter = false;
+ }
+ }
+ };
+
+ $scope.removeStartFilterText = function(gridColumnId){
+ $scope.filterText[gridColumnId].start = undefined;
+ };
+
+ $scope.removeEndFilterText = function(gridColumnId){
+ $scope.filterText[gridColumnId].end = undefined;
+ };
+
+ $scope.showDashboard = function(tei){
+ $location.path('/dashboard').search({tei: tei.id,
+ program: $scope.selectedProgram ? $scope.selectedProgram.id: null});
+ };
});
\ No newline at end of file
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/overdue-events.html'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/overdue-events.html 2014-08-27 15:40:36 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/overdue-events.html 2014-09-09 13:26:15 +0000
@@ -4,8 +4,8 @@
<div id="leftBar">
<div class="left-bar-menu" ng-controller="LeftBarMenuController">
<ul class="nav nav-pills nav-stacked">
- <li><a href ng-click="showHome()">{{'registration_and_data_entry' | translate}}</a></li>
- <li><a href ng-click="showReportTypes()">{{'reports' | translate}}</a></li>
+ <li><a href ng-click="showHome()">{{'registration_and_data_entry'| translate}}</a></li>
+ <li><a href ng-click="showReportTypes()">{{'reports'| translate}}</a></li>
</ul>
</div>
<div id="orgUnitTree" style="margin-top:20px">
@@ -18,55 +18,172 @@
<!--- selected org unit ends -->
</div>
-<div id="mainPage" class="bordered-div">
- <h2>{{'overdue_events' | translate}}</h2>
+<div id="mainPage" class="page">
+
+ <!-- top bar begins -->
+ <div class="row top-bar">
+ <div class="col-sm-12">
+ {{'overdue_events'| translate}}
+ <div class="pull-right">
+ <div class="btn-group" dropdown is-open="status.isopen">
+ <button type="button" class="btn btn-default dropdown-toggle" ng-disabled="!teiList.length">
+ <i class="fa fa-cog" title="{{'settings'| translate}}"></i>
+ </button>
+ <ul class="dropdown-menu pull-right" role="menu">
+ <li ng-show="teiList.length > 0"><a href ng-click="showHideColumns()">{{'show_hide_columns'| translate}}</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- top bar ends -->
+
+ <!--input form begins -->
<form name="outerForm" novalidate>
<div class="row">
- <div class="col-sm-12 col-md-8">
+ <div class="col-sm-8 col-md-6">
<table class="table table-borderless table-striped">
<tr>
- <td class='col-sm-6 col-md-4 vertical-center'>
- {{'program' | translate}}
+ <td class='col-sm-4 col-md-3 vertical-center'>
+ {{'program'| translate}}
</td>
- <td class='col-sm-6 col-md-4'>
+ <td class='col-sm-4 col-md-3'>
<select ng-model="selectedProgram"
class="form-control"
ng-options="program as program.name for program in programs | orderBy: 'name'"
ng-disabled="programs.length < 1">
- <option value="">{{programs.length > 0 ? 'please_select_a_program' : 'no_program_exists' | translate}}</option>
+ <option value="">{{programs.length > 0 ? 'please_select_a_program' : 'no_program_exists'| translate}}</option>
</select>
</td>
</tr>
<tr>
- <td class='col-sm-6 col-md-4 vertical-center'>{{'org_unit'| translate}}</td>
- <td class='col-sm-6 col-md-4'>
+ <td class='col-sm-4 col-md-3 vertical-center'>{{'org_unit'| translate}}</td>
+ <td class='col-sm-4 col-md-3'>
<label><input type="radio" ng-model="selectedOuMode.name" name="selected" value="SELECTED"> {{'SELECTED'| translate}}</label><br/>
<label><input type="radio" ng-model="selectedOuMode.name" name="children" value="CHILDREN"> {{'CHILDREN'| translate}}</label><br/>
<label><input type="radio" ng-model="selectedOuMode.name" name="descendants" value="DESCENDANTS"> {{'DESCENDANTS'| translate}}</label><br/>
<label><input type="radio" ng-model="selectedOuMode.name" name="accessible" value="ACCESSIBLE"> {{'ACCESSIBLE'| translate}}</label>
</td>
</tr>
+ <tr>
+ <label>
+ <td class='col-sm-4 col-md-3 vertical-center'>
+ {{'filter'| translate}}
+ </td>
+ <td>
+ <label>
+ <input type="checkbox" ng-change="markForFollowup()" ng-model="displayMode.onlyMarkedFollowup"/> {{'only_marked_for_followup' | translate}}
+ </label>
+ </td>
+ </label>
+ </tr>
</table>
</div>
</div>
- <div class="row">
+ <div class="row">
<div class="col-sm-8 col-md-6">
- <table class="table-borderless">
- <tr>
- <td>
- <input type="text" name="reportStartDate" placeholder="{{'start_date'| translate}} (yyyy-mm-dd)" class="form-control" ng-date ng-model="report.startDate" max="today" ng-required="true"/>
- <span ng-show="outerForm.submitted && outerForm.reportStartDate.$invalid" style="color:red;font-size:12px">{{'required'| translate}} (yyyy-mm-dd)</span>
- </td>
- <td>
- <input type="text" name="reportEndDate" placeholder="{{'end_date'| translate}} (yyyy-mm-dd)" class="form-control" ng-date ng-model="report.endDate" max="today" ng-required="true"/>
- <span ng-show="outerForm.submitted && outerForm.reportEndDate.$invalid" style="color:red;font-size:12px">{{'required'| translate}} (yyyy-mm-dd)</span>
- </td>
- </tr>
- </table>
- </div>
- <div class="col-md-6 trim">
- <button type="button" class="btn btn-primary" ng-click="generateReport()" ng-disabled="!selectedProgram">{{'go'| translate}}</button>
+ <button type="button" class="btn btn-primary" ng-click="generateReport(selectedProgram, report, selectedOuMode)" ng-disabled="!selectedProgram">{{'go'| translate}}</button>
+ </div>
+ </div>
+
+ <div class="row" ng-if="programs.length < 1">
+ <div class="col-sm-8 col-md-6 vertical-spacing">
+ <div class="alert alert-warning">{{'no_program_exists_report'| translate}}</div>
+ </div>
+ </div>
+ <div class="row" ng-if="programs.length > 0 && !selectedProgram">
+ <div class="col-sm-8 col-md-6 vertical-spacing">
+ <div class="alert alert-warning">{{'please_select_program_report'| translate}}</div>
</div>
</div>
</form>
-</div>
+ <!--input form ends -->
+
+ <img src="../images/ajax-loader-bar.gif" ng-if="reportStarted && !reportFinished"/>
+
+ <!-- upcoming events list begins -->
+ <div ng-if="reportFinished">
+
+ <div ng-switch="teiList.length">
+ <div ng-switch-when="undefined">
+ <div class="alert alert-warning vertical-spacing">
+ {{'no_data_found'| translate}}
+ </div>
+ </div>
+ <div ng-switch-when="0">
+ <div class="alert alert-warning vertical-spacing">
+ {{'no_data_found'| translate}}
+ </div>
+ </div>
+ <div ng-switch-default>
+ <!-- report begins -->
+ <div class="vertical-spacing">
+ <table class="listTable dhis2-table-striped-border dhis2-table-hover">
+ <thead>
+ <tr>
+ <th ng-show="gridColumn.show" ng-repeat="gridColumn in gridColumns">
+
+ <!-- sort icon begins -->
+ <span ng-click="sortTEIGrid(gridColumn)">
+ {{gridColumn.name| translate}}
+ <i ng-if="sortHeader == gridColumn.id && reverse" class="fa fa-sort-desc"></i>
+ <i ng-if="sortHeader == gridColumn.id && !reverse" class="fa fa-sort-asc"></i>
+ </span>
+ <!-- sort icon ends -->
+
+ <!-- filter icon begins -->
+ <span class='pull-right'>
+ <span ng-show="gridColumn.type != 'date' && gridColumn.type != 'int'">
+ <a href ng-click="searchInGrid(gridColumn)" title="{{'search'| translate}}"><span ng-class="{true: 'filter - without - content', false: 'filter - with - content'} [filterText[gridColumn.id] == undefined || filterText[gridColumn.id] == '']"><i class="fa fa-search"></i></span></a>
+ </span>
+ <span ng-show="gridColumn.type === 'date' || gridColumn.type === 'int'">
+ <a href ng-click="searchInGrid(gridColumn)" title="{{'search'| translate}}"><span ng-class="{true: 'filter - without - content', false: 'filter - with - content'} [(filterText[gridColumn.id].start == undefined || filterText[gridColumn.id].start == '') && (filterText[gridColumn.id].end == undefined || filterText[gridColumn.id].end == '')]"><i class="fa fa-search"></i></span></a>
+ </span>
+ </span>
+ <!-- filter icon ends -->
+
+ <!-- filter input field begins -->
+ <span ng-show="gridColumn.showFilter">
+ <span ng-switch="gridColumn.type">
+ <span ng-switch-when="int">
+ <input style="width: 45%;" placeholder="{{'lower_limit'| translate}}" type="number" ng-model="filterText[gridColumn.id].start" ng-blur="searchInGrid(gridColumn)">
+ <input style="width: 45%;" placeholder="{{'upper_limit'| translate}}" type="number" ng-model="filterText[gridColumn.id].end" ng-blur="searchInGrid(gridColumn)">
+ </span>
+ <span ng-switch-when="date">
+ <input style="width: 70%;" placeholder="{{'start_date'| translate}}" type="text" ng-model="filterText[gridColumn.id].start" data-ng-date readonly="readonly">
+ <span ng-hide="filterText[gridColumn.id].start == undefined || filterText[gridColumn.id].start == ''">
+ <a href ng-click='removeStartFilterText(gridColumn.id)'><span class='black'><i class="fa fa-trash-o"></i></span></a>
+ </span>
+ <input style="width: 70%;" placeholder="{{'end_date'| translate}}" type="text" ng-model="filterText[gridColumn.id].end" data-ng-date readonly="readonly">
+ <span ng-hide="filterText[gridColumn.id].end == undefined || filterText[gridColumn.id].end == ''">
+ <a href ng-click='removeEndFilterText(gridColumn.id)'><span class='black'><i class="fa fa-trash-o"></i></span></a>
+ </span>
+ </span>
+ <span ng-switch-default>
+ <input type="text" style="width: 90%;" ng-model="filterText[gridColumn.id]" ng-blur="searchInGrid(gridColumn)">
+ </span>
+ </span>
+ </span>
+ <!-- filter input field ends -->
+
+ </th>
+ </tr>
+ </thead>
+ <tbody id="list">
+ <tr ng-repeat="tei in teiList| orderBy:sortHeader:reverse | gridFilter:filterText:filterTypes"
+ ng-click="showDashboard(tei)"
+ title="{{'go_to_dashboard'| translate}}">
+ <td ng-show="gridColumn.show"
+ ng-repeat="gridColumn in gridColumns" ng-if='displayMode.onlyMarkedFollowup ? tei.followup:true'>
+ {{tei[gridColumn.id]}}
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <!-- report ends -->
+ </div>
+ </div>
+ </div>
+ <!-- upcoming events list ends -->
+</div>
\ No newline at end of file
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/upcoming-events-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/upcoming-events-controller.js 2014-09-09 12:54:28 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/report/upcoming-events-controller.js 2014-09-09 13:26:15 +0000
@@ -11,7 +11,6 @@
AttributesFactory,
ProgramFactory,
DHIS2EventFactory,
- ContextMenuSelectedItem,
storage) {
TranslationService.translate();
@@ -46,10 +45,8 @@
//watch for selection of program
$scope.$watch('selectedProgram', function() {
- if( angular.isObject($scope.selectedProgram)){
- $scope.reportFinished = false;
- $scope.reportStarted = false;
- }
+ $scope.reportFinished = false;
+ $scope.reportStarted = false;
});
$scope.generateReport = function(program, report, ouMode){