Skip to content

Commit

Permalink
Merge 516be03 into 1920783
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmiller committed Mar 9, 2017
2 parents 1920783 + 516be03 commit 0f3dceb
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 86 deletions.
178 changes: 95 additions & 83 deletions opal/static/js/opal/services/episode.js
@@ -1,135 +1,146 @@
//
// This is the main Episode class for OPAL.
// This is the main Episode class for Opal
//
angular.module('opal.services')
.factory('Episode', function(
$http, $q, $rootScope, $routeParams, $window,
Item, RecordEditor, FieldTranslater) {
var DATE_FORMAT = 'DD/MM/YYYY';
"use strict";

Episode = function(resource) {
var episode = this;
var column, field, attrs;

episode.recordEditor = new RecordEditor(episode);

// We would like everything for which we have data that is a field to
// be an instantiated instance of Item - not just those fields in the
// currently applicable schema.
_.each($rootScope.fields, function(field){
if(resource[field.name]){
resource[field.name] = _.map(
resource[field.name],
function(attrs){ return new Item(attrs, episode, field); });
if(field.sort){
resource[field.name] = _.sortBy(resource[field.name], field.sort).reverse();
}
}else{ resource[field.name] = []; }
});
// TODO: Set this with a more idiomatic Angular way, and set it once.
var DATE_FORMAT = 'DD/MM/YYYY';
var Episode = function(resource) {
this.initialise(resource);
}

// Sort a particular column according to schema params.
this.sortColumn = function(columnName, sortBy){
episode[columnName] = _.sortBy(episode[columnName], sortBy).reverse();
}
// TODO - Pull these from the schema? Also cast them to moments
// Note - these are date fields on the episode itself - which is not currently
// serialised and sent with the schema !
var date_fields = ['date_of_admission', 'discharge_date', 'date_of_episode', 'start', 'end'];

//
// TODO - Pull these from the schema? Also cast them to moments
// Note - these are date fields on the episode itself - which is not currently
// serialised and sent with the schema !
var date_fields = ['date_of_admission', 'discharge_date', 'date_of_episode', 'start', 'end'];
Episode.prototype = {

// Constructor to update from attrs and parse datish fields
this.initialise = function(attrs){
angular.extend(episode, attrs)
initialise: function(data){
var self = this;
// We would like a way to open a modal that edits subrecords.
self.recordEditor = new RecordEditor(self); // TODO: Rename or refactor this.

// We would like everything for which we have data that is a field to
// be an instantiated instance of Item
_.each($rootScope.fields, function(field){
if(data[field.name]){
data[field.name] = _.map(
data[field.name],
function(attrs){ return new Item(attrs, self, field); });
if(field.sort){
data[field.name] = _.sortBy(data[field.name], field.sort).reverse();
}
}else{ data[field.name] = []; }
});
angular.extend(self, data)
// Convert string-serialised dates into native JavaScriptz
_.each(date_fields, function(field){
if(attrs[field]){
var parsed = moment(attrs[field], DATE_FORMAT);
episode[field] = parsed.toDate();
if(data[field]){
var parsed = moment(data[field], DATE_FORMAT);
self[field] = parsed.toDate();
}
});
if(!episode.demographics || episode.demographics.length == 0 || !episode.demographics[0].patient_id){
if(!self.demographics || self.demographics.length == 0 || !self.demographics[0].patient_id){
throw "Episode() initialization data must contain demographics with a patient id."
}
this.link = "/patient/" + episode.demographics[0].patient_id + "/" + episode.id;
};
self.link = "/patient/" + self.demographics[0].patient_id + "/" + self.id;

this.getNumberOfItems = function(columnName) {
return episode[columnName].length;
};
},

// Sort a particular column according to schema params.
sortColumn: function(columnName, sortBy){
this[columnName] = _.sortBy(this[columnName], sortBy).reverse();
},

getNumberOfItems: function(columnName) {
return this[columnName].length;
},

// Getter function to return active episode tags.
// Default implementation just hits tagging
this.getTags = function(){
getTags: function(){
if(this.tagging[0].makeCopy){
var tags = this.tagging[0].makeCopy()
}else{
var tags = this.tagging[0]
}
delete tags.id
return _.filter(_.keys(tags), function(t){return tags[t]})
};
},

//
// Boolean predicate function to determine whether
// this episode has the given TAG
//
this.hasTag = function(tag){
hasTag: function(tag){
return this.getTags().indexOf(tag) != -1;
}
},

this.newItem = function(columnName, opts) {
//
// Create a new Item of type COLUMNNAME
//
newItem: function(columnName, opts) {
var self = this;
if(!opts){ opts = {}; }

if(!opts.column){
opts.column = $rootScope.fields[columnName];
}

var attrs = {};
return new Item(attrs, episode, opts.column);
};
return new Item(attrs, self, opts.column);
},

getItem: function(columnName, iix) {
return this[columnName][iix];
},

this.getItem = function(columnName, iix) {
return episode[columnName][iix];
};

//
// add an item (e.g. instance of a subfield) to this episode
// add an item (e.g. instance of a subrecord) to this episode
//
this.addItem = function(item) {
addItem: function(item) {
// Sometimes we add an item from a non-active schema.
if(!episode[item.columnName]){
episode[item.columnName] = [];
// TODO: Do we really do this any more?
if(!this[item.columnName]){
this[item.columnName] = [];
}
episode[item.columnName].push(item);
this[item.columnName].push(item);
if(item.sort){
this.sortColumn(item.columnName, item.sort);
}
};
},

this.removeItem = function(item) {
var items = episode[item.columnName];
for (iix = 0; iix < items.length; iix++) {
removeItem: function(item) {
var items = this[item.columnName];
for (var iix = 0; iix < items.length; iix++) {
if (item.id == items[iix].id) {
items.splice(iix, 1);
break;
};
};
};
},

this.makeCopy = function(){
makeCopy: function(){
var copy = {
id : episode.id,
category_name : episode.category_name,
date_of_admission: episode.date_of_admission,
date_of_episode : episode.date_of_episode,
discharge_date : episode.discharge_date,
consistency_token: episode.consistency_token
id : this.id,
category_name : this.category_name,
date_of_admission: this.date_of_admission,
date_of_episode : this.date_of_episode,
discharge_date : this.discharge_date,
consistency_token: this.consistency_token
}
return copy
};
},

this.compare = function(other, comparators) {
compare: function(other, comparators) {
var self = this;
//
// The default comparators we use for our Episode sorting in lists
//
Expand All @@ -150,7 +161,7 @@ angular.module('opal.services')

var v1, v2;
for (var ix = 0; ix < comparators.length; ix++) {
v1 = comparators[ix](episode);
v1 = comparators[ix](self);
v2 = comparators[ix](other);
if (v1 < v2) {
return -1;
Expand All @@ -160,7 +171,7 @@ angular.module('opal.services')
}

return 0;
};
},

//
// Save our Episode.
Expand All @@ -169,11 +180,12 @@ angular.module('opal.services')
// 2. Send our data to the server
// 3. Handle the response.
//
this.save = function(attrs){
save: function(attrs){
var self = this;
var value;
var deferred = $q.defer();
var url = '/api/v0.1/episode/' + attrs.id + '/';
method = 'put';
var method = 'put';

_.each(date_fields, function(field){
if(attrs[field]){
Expand All @@ -189,7 +201,7 @@ angular.module('opal.services')

$http[method](url, attrs).then(
function(response){
episode.initialise(response.data);
self.initialise(response.data);
deferred.resolve();
},
function(response) {
Expand All @@ -204,18 +216,17 @@ recently changed it - refresh the page and try again');
);

return deferred.promise;
};
},


//
// Predicate to determine whether this episode is discharged or not
//
this.isDischarged = function(){
return episode.location[0].category == 'Discharged' ||
(episode.discharge_date && moment(episode.discharge_date).isBefore(moment()));
isDischarged: function(){
return this.location[0].category == 'Discharged' ||
(this.discharge_date && moment(this.discharge_date).isBefore(moment()));
}

this.initialise(resource)
};
}; // Closes prototype

//
// takes two arguments, the hospital number and a hash of callbacks.
Expand All @@ -234,7 +245,7 @@ recently changed it - refresh the page and try again');
patients: [],
hospitalNumber: number
};
// record loader is sued by the field translater to
// record loader is used by the field translater to
// cast the results fields
deferred.promise.then(function(result){
if(!result.patients.length){
Expand Down Expand Up @@ -262,4 +273,5 @@ recently changed it - refresh the page and try again');
}
}
return Episode

});
2 changes: 1 addition & 1 deletion opal/static/js/test/discharge.controller.test.js
Expand Up @@ -157,7 +157,7 @@ describe('DischargeEpisodeCtrl', function(){

$httpBackend.expectPUT('/api/v0.1/tagging/555/').respond({});
$httpBackend.expectPOST('/api/v0.1/location/').respond({});
$httpBackend.expectPUT('/api/v0.1/episode/555/').respond({});
$httpBackend.expectPUT('/api/v0.1/episode/555/').respond(episodeData);
spyOn(modalInstance, 'close')

$scope.discharge();
Expand Down
10 changes: 9 additions & 1 deletion opal/static/js/test/episode.service.test.js
Expand Up @@ -290,7 +290,15 @@ describe('Episode', function() {
id : 555,
active : true,
date_of_admission: '20/11/2013',
discharge_date : null
discharge_date : null,
demographics: [{
id: 101,
patient_id: 99,
first_name: 'John',
surname: "Smith",
date_of_birth: '31/07/1980',
hospital_number: '555'
}]
};

episode = new Episode(episodeData);
Expand Down
1 change: 1 addition & 0 deletions opal/static/js/test/patient_detail.controller.test.js
Expand Up @@ -79,6 +79,7 @@ describe('PatientDetailCtrl', function(){

beforeEach(function(){
module('opal');
var Episode;

inject(function($injector){
$rootScope = $injector.get('$rootScope');
Expand Down
2 changes: 1 addition & 1 deletion opal/static/js/test/undischarge.controller.test.js
Expand Up @@ -75,7 +75,7 @@ describe('UndischargeCtrl', function() {

it('should confirm', function() {
$httpBackend.expectGET('/api/v0.1/userprofile/').respond({});
$httpBackend.expectPUT('/api/v0.1/episode/221/').respond({});
$httpBackend.expectPUT('/api/v0.1/episode/221/').respond(episodeData);
$httpBackend.expectPUT('/api/v0.1/location/12/').respond({});
$scope.confirm();
$rootScope.$apply();
Expand Down

0 comments on commit 0f3dceb

Please sign in to comment.