Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

Commit

Permalink
Added additional criteria to appointment search
Browse files Browse the repository at this point in the history
Resolves #71
  • Loading branch information
jkleinsc committed Jul 7, 2015
1 parent 5530ca2 commit 71d8a6a
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 49 deletions.
7 changes: 2 additions & 5 deletions app/appointments/edit/controller.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import AbstractEditController from 'hospitalrun/controllers/abstract-edit-controller';
import AppointmentStatuses from 'hospitalrun/mixins/appointment-statuses';
import Ember from 'ember';
import PatientSubmodule from 'hospitalrun/mixins/patient-submodule';
import VisitTypes from 'hospitalrun/mixins/visit-types';

export default AbstractEditController.extend(PatientSubmodule, VisitTypes, {
export default AbstractEditController.extend(AppointmentStatuses, PatientSubmodule, VisitTypes, {
needs: ['appointments','pouchdb'],

appointmentStatuses: [
'Scheduled',
'Canceled'
],
dateFormat: 'l h:mm A',
findPatientVisits: false,

Expand Down
61 changes: 49 additions & 12 deletions app/appointments/search/controller.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,55 @@
import AppointmentIndexController from 'hospitalrun/appointments/index/controller';
import AppointmentStatuses from 'hospitalrun/mixins/appointment-statuses';
import Ember from 'ember';
export default AppointmentIndexController.extend({
import VisitTypes from 'hospitalrun/mixins/visit-types';
export default AppointmentIndexController.extend(AppointmentStatuses, VisitTypes, {
needs: 'appointments',
appointmentType: null,
physicianList: Ember.computed.alias('controllers.appointments.physicianList'),
provider: null,
queryParams: ['appointmentType', 'provider', 'status', 'startKey', 'startDate'],
searchFields: ['selectedAppointmentType', 'selectedProvider', 'selectedStatus', 'selectedStartDate'],
selectedProvider: null,
selectedStartingDate: new Date(),
selectedStatus: null,
sortProperties: null,
startKey: [],
startingDate: null,
_setup: function() {
this.set('startingDate', new Date());
}.on('init'),
status: null,
visitTypesList: Ember.computed.alias('controllers.appointments.visitTypeList'),

startingDateChanged: function() {
var startingDate = this.get('startingDate');
this.set('previousStartKey');
this.set('previousStartKeys',[]);
if (!Ember.isEmpty(startingDate)) {
this.set('startKey', [startingDate.getTime(),null,null]);
actions: {
search: function() {
var appointmentType = this.get('selectedAppointmentType'),
fieldsToSet = {
startKey: [],
previousStartKey: null,
previousStartKeys: []
},
provider = this.get('selectedProvider'),
status = this.get('selectedStatus'),
startDate = this.get('selectedStartingDate');

if (Ember.isEmpty(appointmentType)) {
fieldsToSet.appointmentType = null;
} else {
fieldsToSet.appointmentType = appointmentType;
}
if (Ember.isEmpty(provider)) {
fieldsToSet.provider = null;
} else {
fieldsToSet.provider = provider;
}
if (Ember.isEmpty(status)) {
fieldsToSet.status = null;
} else {
fieldsToSet.status = status;
}
if (!Ember.isEmpty(startDate)) {
fieldsToSet.startDate = startDate.getTime();
}
if (!Ember.isEmpty(fieldsToSet)) {
this.setProperties(fieldsToSet);
}
}
}.observes('startingDate')
}
});
30 changes: 19 additions & 11 deletions app/appointments/search/route.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
import AppointmentIndexRoute from 'hospitalrun/appointments/index/route';
import Ember from 'ember';
export default AppointmentIndexRoute.extend({
editReturn: 'appointments.search',
editReturn: 'appointments.search',
filterParams: ['appointmentType', 'provider', 'status'],
modelName: 'appointment',
pageTitle: 'Search Appointments',

queryParams: {
appointmentType: {refreshModel: true},
provider: {refreshModel: true},
status: {refreshModel: true},
startDate: {refreshModel: true},
startKey: {refreshModel: true}
},

_modelQueryParams: function(params) {
var startDate,
maxValue = this.get('maxValue'),
startKey = params.startKey;
if (Ember.isEmpty(startKey)) {
var startDate = params.startDate,
maxValue = this.get('maxValue');
if (Ember.isEmpty(startDate)) {
startDate = moment();
} else {
startDate = moment(startKey[0]);
startDate = moment(parseInt(startDate));
}
var startOfDay = startDate.startOf('day').toDate().getTime();
var endTime = startDate.add(1, 'y').endOf('day').toDate().getTime();
var searchOptions = {
startkey: [startOfDay, null, 'appointment_'],
endkey: [maxValue, maxValue, 'appointment_'+maxValue]
};
return {
options: {
startkey: [startOfDay, null, 'appointment_'],
endkey: [endTime, endTime, 'appointment_'+maxValue]
},
options: searchOptions,
mapReduce: 'appointments_by_date'
};
}
Expand Down
29 changes: 23 additions & 6 deletions app/appointments/search/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,36 @@
<div class="panel-body">
{{#em-form model=this submit_button=false }}
<div class="row">
{{date-picker property="startingDate" label="Show Appointments On Or After" class="col-sm-4"}}
{{date-picker property="selectedStartingDate" label="Show Appointments On Or After" class="col-sm-3"}}
{{em-select class="col-sm-3" prompt=" " property="selectedStatus"
label="Status" content=appointmentStatuses
optionValuePath="content" optionLabelPath="content"
}}
</div>
<div calss="row">
{{em-select class="col-sm-3" prompt=" " label="Type"
property="selectedAppointmentType" content=visitTypes
optionValuePath="content" optionLabelPath="content"
}}
{{em-select class="col-sm-3" prompt=" " property="selectedProvider"
label="With" content=physicianList.value
optionValuePath="content" optionLabelPath="content"
}}
</div>
{{/em-form}}
</div>
<div class="panel-footer">
<button class="btn btn-default" {{action 'search'}}>Search</button>
</div>
</div>
<table class="table">
<tr class="table-header">
<th>Date</th>
{{#sortable-column sortBy='date' sortDesc=sortDesc sortKey=sortKey }}Date{{/sortable-column}}
<th>Name</th>
<th>Type</th>
<th>Location</th>
<th>Provider</th>
<th>Status</th>
{{#sortable-column sortBy='appointmentType' sortDesc=sortDesc sortKey=sortKey }}Type{{/sortable-column}}
{{#sortable-column sortBy='location' sortDesc=sortDesc sortKey=sortKey }}Location{{/sortable-column}}
{{#sortable-column sortBy='provider' sortDesc=sortDesc sortKey=sortKey }}With{{/sortable-column}}
{{#sortable-column sortBy='status' sortDesc=sortDesc sortKey=sortKey }}Status{{/sortable-column}}
<th>Actions</th>
</tr>
{{#each itemController='appointments/item'}}
Expand Down
7 changes: 7 additions & 0 deletions app/mixins/appointment-statuses.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Ember from "ember";
export default Ember.Mixin.create({
appointmentStatuses: [
'Scheduled',
'Canceled'
],
});
93 changes: 78 additions & 15 deletions app/utils/pouch-views.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* global emit */
/* global req */
/* global compareStrings */
/* global getCompareDate */

function createDesignDoc(item, rev) {
var ddoc = {
Expand All @@ -21,17 +22,25 @@ function createDesignDoc(item, rev) {
return ddoc;
}

function generateSortFunction(sortFunction) {
return 'function(head, req) {' +
function generateSortFunction(sortFunction, includeCompareDate, filterFunction) {
var generatedFunction = 'function(head, req) {' +
'function keysEqual(keyA, keyB) {' +
'for (var i= 0; i < keyA.length; i++) {' +
'if (keyA[i] !== keyB[i]) {'+
'return false;'+
'}'+
'}'+
'return true;'+
'}'+
'function compareStrings(aString, bString) {'+
'}';
if (includeCompareDate) {
generatedFunction += 'function getCompareDate(dateString) {'+
'if (!dateString || dateString === "") {'+
'return 0;'+
'}'+
'return new Date(dateString).getTime();'+
'}';
}
generatedFunction += 'function compareStrings(aString, bString) {'+
'if (!aString) {'+
'aString = "";'+
'}'+
Expand All @@ -51,8 +60,11 @@ function generateSortFunction(sortFunction) {
'startingPosition = 0;'+
'while(row = getRow()) {'+
'rows.push(row);'+
'}'+
'rows.sort('+sortFunction+');'+
'}';
if (filterFunction) {
generatedFunction += 'rows = rows.filter('+filterFunction+');';
}
generatedFunction += 'rows.sort('+sortFunction+');'+
'if (req.query.sortStartKey) {'+
'var startKey = JSON.parse(req.query.sortStartKey);'+
'for (var i=0; i<rows.length; i++) {'+
Expand All @@ -72,6 +84,7 @@ function generateSortFunction(sortFunction) {
'}'+
'send(JSON.stringify({"rows" : rows}));'+
'}';
return generatedFunction;
}

function updateDesignDoc(item, db, rev) {
Expand Down Expand Up @@ -113,7 +126,64 @@ var designDocs = [{
}
}
},
version: 2
sort: generateSortFunction(function(a,b) {
function defaultStatus(value) {
if (!value || value === '') {
return 'Scheduled';
} else {
return value;
}
}
var sortBy = '';
if (req.query && req.query.sortKey) {
sortBy = req.query.sortKey;
}
switch(sortBy) {
case 'appointmentType':
case 'location':
case 'provider':
return compareStrings(a.doc[sortBy], b.doc[sortBy]);
case 'date': {
var startDiff = getCompareDate(a.doc.startDate) -getCompareDate(b.doc.startDate);
if (startDiff === 0) {
return getCompareDate(a.doc.endDate) -getCompareDate(b.doc.endDate);
} else {
return startDiff;
}
break;
}
case 'status': {
var aStatus = defaultStatus(a.doc[sortBy]),
bStatus = defaultStatus(b.doc[sortBy]);
return compareStrings(aStatus, bStatus);
}
default: {
return 0; //Don't sort
}
}
}.toString(), true, function(row) {
var i,
filterBy = null,
includeRow = true;
if (req.query && req.query.filterBy) {
filterBy = JSON.parse(req.query.filterBy);
}
if (!filterBy) {
return true;
}
for (i=0; i < filterBy.length; i++) {
var currentValue = row.doc[filterBy[i].name];
if (filterBy[i].name === 'status' && (!currentValue || currentValue === '')) {
currentValue = 'Scheduled';
}
if (currentValue !== filterBy[i].value) {
includeRow = false;
break;
}
}
return includeRow;
}.toString()),
version: 3
}, {
name: 'appointments_by_patient',
function: function(doc) {
Expand Down Expand Up @@ -387,13 +457,6 @@ var designDocs = [{
}
},
sort: generateSortFunction(function(a,b) {
function getCompareDate(dateString) {
if (!dateString || dateString === '') {
return 0;
}
return new Date(dateString).getTime();
}

var sortBy = '';
if (req.query && req.query.sortKey) {
sortBy = req.query.sortKey;
Expand All @@ -412,7 +475,7 @@ var designDocs = [{
return 0; //Don't sort
}
}
}.toString()),
}.toString(), true),
version: 3
}, {
name: 'photo_by_patient',
Expand Down

0 comments on commit 71d8a6a

Please sign in to comment.