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

Commit

Permalink
Visit Reports (#991)
Browse files Browse the repository at this point in the history
* added basic translations for report

* feat: added report model

* feat: added report tabs to visit page

* feat: added report route to router

* feat: added report page

* feat: reports to visits children

* feat: added add/delete report capabilities

* fix: fixed diagnosisContainer issue on browser back history button

* fix: display different report title based on type of visit

* Modified Package.json for new NPM Deployment

* fix: added next appointment and operative plans to opd form

* Restore package.json to working state

* Implement custom forms for OPD Report

* Add custom forms attribute to report model

* fix: saved report object

* fix: added preview report feat

* fix: added report by visit view

* fix: added logic to show different report sections

* fix: added some report translations

* fix: edited report model

* fix: implemented logic to toggle between show report and new report

* Remove preview functionality from OPD Reports

* Implement print button

* Remove print section header

* Write styles and markup for print page

* Refactor report header into partial

* Rename report types

* fix style lint errors

* fix: completed internationalization and lint fix

* 0.9.18

* Incremented version number, added scope

* fix: remove patientId field, fixed next appointment bug, removed unused translation

* fix: change date fields to simple text

* fix: fixed bug that has to do with page header title

* Added .travis.yml file for building and deploying to npm

* Removed ember test. Pretty much does the same as npm test

* Allowing all branches to be tested and built

* fix: added translations for discharge report

* fix: modified report model to accommodate discharge report

* fix: added discharge report

* fix: added next appointment date to discharge report on save

* fix: implemented next appointment as a mixin

* fix: added translations for followup appointment message

* fix: made sure a followup appointment exists before you generate discharge report

* Add Hospital Info report header as option config

* Add report model to patient-diagnosis and visit unit tests

* fix: fixed report header conflict

* Refactor report template

* Add custom forms to discharge report

* fix: added hospital info doc to environment

* fix: create sample docs on couchdb

* Change how "new" routes work

Makes sure that if user redirects to url the patient is properly
selected.

* fix: made sure sample docs are created when deleted

* Add query parameters to improve app navigation experience

* set patient on visit models

* Redirect reports/new to patients when no visit model

* Clean up visit controller

* Set visit on models

* Update visit acceptance tests

* Fix appointments new surgery test error

* Remove double reference to visits controller

* Display visit diagnosis appropriately

* Fix Operative Plans display

* fix: fixed translation lables for next appointments

* fix: modified get futureAppointment to work for list of appointments

* fix: implemented next appointments on both template and controller

* fix: fix lint

* FIx next appointments display

* Added auto trigger hospitalrun-server refresh script on successful build

* Fix reports controller bug

* Add diagnosis container

* Set patient on model if model is not new

* Set visit on controller and add display current operative plan

* Add `Completed By` field to report

* Refactor reports template

* Ensure reports.edit returns to visits.edit

* Display patient procedures on report

* Remove discharge report compulsory next appointment modal

* Fix `completed by` on report page

* Style select element properly; Add titles to report

* fix: fix  new user title bug after a new user has been added

* Added deploy branches to .travis.yml

* fix: fix  test for new user title bug

* fix: updated report template with testing attributes on fields

* fix: update visit template with testing attributes on fields

* fix: implemented acceptance tests for opd and discharge reports

* Implement acceptance tests for OPD Report

* Refactor code to conform with style guide

* Fix nextAppointment bug
  • Loading branch information
adeolabadmus authored and jkleinsc committed Mar 15, 2017
1 parent 5441db8 commit 88073bc
Show file tree
Hide file tree
Showing 32 changed files with 1,094 additions and 78 deletions.
4 changes: 3 additions & 1 deletion app/admin/custom-forms/edit/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ export default AbstractEditController.extend({
'operativePlan',
'patient',
'socialwork',
'visit'
'visit',
'opdReport',
'dischargeReport'
],

formTypes: computed(function() {
Expand Down
4 changes: 4 additions & 0 deletions app/appointments/edit/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const {
} = Ember;

export default AbstractEditRoute.extend(AddToPatientRoute, PatientListRoute, {

editTitle: t('appointments.editTitle'),
modelName: 'appointment',
newButtonText: t('appointments.buttons.newButton'),
Expand Down Expand Up @@ -59,6 +60,9 @@ export default AbstractEditRoute.extend(AddToPatientRoute, PatientListRoute, {
if (!isEmpty(params.forPatientId)) {
let modelPromise = this._super(params);
return this._setPatientOnModel(modelPromise, params.forPatientId);
} else if (!isEmpty(params.forVisitId)) {
let modelPromise = this._super(params);
return this._setVisitOnModel(modelPromise, params.forVisitId);
} else {
return this._createNewRecord(params);
}
Expand Down
3 changes: 3 additions & 0 deletions app/helpers/date-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export default Ember.Helper.helper(function(params, hash) {
if (hash && hash.format) {
dateFormat = hash.format;
}
if (date && typeof date.get == 'function') {
date = date.get('content');
}
return moment(date).format(dateFormat);
}
});
61 changes: 58 additions & 3 deletions app/locales/en/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ export default {
socialworkFormType: 'Social Work',
text: 'Text',
textarea: 'Large Text',
visitFormType: 'Visit'
visitFormType: 'Visit',
opdReportFormType: 'Outpatient Report',
dischargeReportFormType: 'Discharge Report'
},
messages: {
deleteForm: 'Are you sure you want to delete this custom form?',
Expand Down Expand Up @@ -994,14 +996,16 @@ export default {
statusDischarged: 'Discharged',
statusCheckedIn: 'Checked In',
statusCheckedOut: 'Checked Out',
createNewPatient: 'Create New Patient'
createNewPatient: 'Create New Patient',
reportType: 'Report type'
},
navigation: {
charges: 'Charges',
notes: 'Notes',
orders: 'Orders',
procedures: 'Procedures',
vitals: 'Vitals'
vitals: 'Vitals',
reports: 'Reports'
}
},
labs: {
Expand Down Expand Up @@ -1105,6 +1109,8 @@ export default {
backToPatients: 'Back to Patient List',
newPatient: '+ new patient',
patientCheckIn: 'Patient Check In',
newOPDReport: 'New OPD Report',
newDischargeReport: 'New Discharge Report',
scheduleSurgery: 'Schedule Surgery'
},
labels: {
Expand Down Expand Up @@ -1234,6 +1240,55 @@ export default {
addMedication: 'Add Medication'
}
},
reports: {
titles: {
saved: 'Report saved',
opdTitle: 'OPD Report',
dischargeReport: 'Discharge Report'
},
form: {
visitDate: 'Date of Visit',
admissionDate: 'Admission Date',
dischargeDate: 'Discharge Date',
notes: {
title: 'Notes',
date: 'Date',
author: 'Author'
},
primaryDiagnosis: 'Primary Diagnosis',
secondaryDiagnosis: 'Secondary Diagnosis',
procedures: 'Procedures',
allProcedures: 'All Procedures Performed',
labs: 'Labs',
images: 'Images',
medications: 'Medications',
nextAppointment: 'Next Appointment',
nextAppointments: 'Next Appointments',
operativePlan: {
title: 'Operative Plan',
description: 'Operation Description',
procedures: 'Planned Procedures',
instructions: 'Instructions upon Admission'
},
completedBy: 'Completed By'
},
opd: {
titles: {
new: 'New OPD Report',
edit: 'Edit OPD Report'
}
},
discharge: {
titles: {
new: 'New Discharge Report',
edit: 'Edit Discharge Report'
}
},
messages: {
delete: 'Are you sure you wish to delete this report?',
saved: 'The report has been saved.'
}
},
components: {
chargesByTypeTab: {
charges: 'charges'
Expand Down
2 changes: 1 addition & 1 deletion app/medication/edit/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default AbstractEditController.extend(AddNewPatient, FulfillRequest, Inve
prescriptionClass: function() {
let quantity = this.get('model.quantity');
if (Ember.isEmpty(quantity)) {
return 'required';
return 'required test-medication-prescription';
}
}.property('model.quantity'),

Expand Down
2 changes: 2 additions & 0 deletions app/medication/edit/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export default AbstractEditRoute.extend(AddToPatientRoute, FulfillRequest, Inven
if (!Ember.isEmpty(idParam) && params[idParam] === 'new' || params[idParam] === 'dispense') {
if (!isEmpty(params.forPatientId)) {
return this._setPatientOnModel(modelPromise, params.forPatientId);
} else if (!isEmpty(params.forVisitId)) {
return this._setVisitOnModel(modelPromise, params.forVisitId);
} else {
return this._createNewRecord(params);
}
Expand Down
29 changes: 27 additions & 2 deletions app/mixins/add-to-patient-route.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,23 @@ export default Mixin.create({
queryParams: {
forPatientId: {
refreshModel: false
},
forVisitId: {
refreshModel: false
}
},

model(params) {
let idParam = get(this, 'idParam');
let modelPromise = this._super(params);
if (!isEmpty(params.forPatientId) && params[idParam] === 'new') {
return this._setPatientOnModel(modelPromise, params.forPatientId);
if (params[idParam] === 'new') {
if (!isEmpty(params.forPatientId)) {
return this._setPatientOnModel(modelPromise, params.forPatientId);
} else if (!isEmpty(params.forVisitId)) {
return this._setVisitOnModel(modelPromise, params.forVisitId);
} else {
return this._createNewRecord(params);
}
} else {
return modelPromise;
}
Expand All @@ -32,5 +41,21 @@ export default Mixin.create({
return model;
});
});
},

/**
* Resolves the model promise and then sets the visit information on the model.
*/
_setVisitOnModel(modelPromise, visitId) {
let store = get(this, 'store');
return modelPromise.then((model) => {
return store.find('visit', visitId).then((visit) => {
model.set('visit', visit);
model.set('returnToVisit', visitId);
model.set('selectPatient', false);
model.set('patient', visit.get('patient'));
return model;
});
});
}
});
12 changes: 12 additions & 0 deletions app/mixins/patient-submodule.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,17 @@ export default Ember.Mixin.create(PatientVisits, {
});
}.property('model.patient.id', 'newVisitAdded'),

patientProcedures: Ember.computed('patientVisits.[]', function() {
let patient = get(this, 'model.patient');
return DS.PromiseArray.create({
promise: get(this, 'patientVisits').then((patientVisits) => {
return get(patient, 'operationReports').then((operationReports) => {
return this._getPatientProcedures(operationReports, patientVisits);
});
})
});
}),

patientVisitsForSelect: function() {
return DS.PromiseArray.create({
promise: this.get('patientVisits').then(function(patientVisits) {
Expand Down Expand Up @@ -227,6 +238,7 @@ export default Ember.Mixin.create(PatientVisits, {
promises.push(visit.get('medication'));
promises.push(visit.get('procedures'));
promises.push(visit.get('vitals'));
promises.push(visit.get('reports'));
}
return promises;
},
Expand Down
63 changes: 61 additions & 2 deletions app/mixins/patient-visits.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import Ember from 'ember';
import PouchDbMixin from 'hospitalrun/mixins/pouchdb';
import VisitStatus from 'hospitalrun/utils/visit-statuses';

import DS from 'ember-data';
import moment from 'moment';
const {
isEmpty
isEmpty,
get
} = Ember;

export default Ember.Mixin.create(PouchDbMixin, {
Expand All @@ -20,6 +22,63 @@ export default Ember.Mixin.create(PouchDbMixin, {
});
},

getPatientFutureAppointment(visit, outPatient) {
let patientId = get(visit, 'patient.id');
let visitDate = get(visit, 'startDate');
let maxValue = get(this, 'maxValue');
let promise = this.store.query('appointment', {
options: {
startkey: [patientId, null, null, 'appointment_'],
endkey: [patientId, maxValue, maxValue, maxValue]
},
mapReduce: 'appointments_by_patient'
}).then(function(result) {
let futureAppointments = result.filter(function(data) {
let startDate = get(data, 'startDate');
return startDate && moment(startDate).isAfter(moment(visitDate), 'day');
}).sortBy('startDate');
if (!futureAppointments.length) {
return null;
}
if (!outPatient) {
let [appointment] = futureAppointments;
return appointment;
} else {
return futureAppointments.slice(0, 3);
}

});
return (outPatient) ? DS.PromiseArray.create({ promise }) : DS.PromiseObject.create({ promise });
},

_getVisitCollection(visits, name) {
let returnList = [];
if (!Ember.isEmpty(visits)) {
visits.forEach(function(visit) {
get(visit, name).then(function(items) {
returnList.addObjects(items);
});
});
}
return returnList;
},

_getPatientProcedures(operationReports, visits) {
let patientProcedures = this._getVisitCollection(visits, 'procedures');
operationReports.forEach((report) => {
let reportedProcedures = get(report, 'procedures');
let surgeryDate = get(report, 'surgeryDate');
reportedProcedures.forEach((procedure) => {
patientProcedures.addObject({
description: get(procedure, 'description'),
procedureDate: surgeryDate,
report
});
});
});
return patientProcedures;
},

checkoutVisit(visit, status) {
visit.set('status', status);
visit.set('endDate', new Date());
Expand Down
17 changes: 17 additions & 0 deletions app/mixins/user-session.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,15 @@ export default Ember.Mixin.create({
'Nurse Manager',
'System Administrator'
],
add_report: [
'Data Entry',
'Doctor',
'Hospital Administrator',
'Medical Records Officer',
'Nurse',
'Nurse Manager',
'System Administrator'
],
admit_patient: [
'Data Entry',
'Doctor',
Expand Down Expand Up @@ -324,6 +333,14 @@ export default Ember.Mixin.create({
'Nurse Manager',
'System Administrator'
],
delete_report: [
'Doctor',
'Hospital Administrator',
'Medical Records Officer',
'Nurse',
'Nurse Manager',
'System Administrator'
],
delete_visit: [
'Doctor',
'Hospital Administrator',
Expand Down
32 changes: 32 additions & 0 deletions app/models/report.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import AbstractModel from 'hospitalrun/models/abstract';
import DS from 'ember-data';

export default AbstractModel.extend({
// Attributes
reportDate: DS.attr('date'),
customForms: DS.attr('custom-forms'),
reportType: DS.attr('string'),
surgeon: DS.attr('string'),

// Associations
visit: DS.belongsTo('visit', { async: false }),

validations: {
visit: {
presence: true
},

reportDate: {
presence: true
},

surgeon: {
presence: {
'if'(object) {
return !object.get('visit.outPatient');
},
message: 'Please select a surgeon'
}
}
}
});
1 change: 1 addition & 0 deletions app/models/visit.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export default AbstractModel.extend({
status: DS.attr('string'),
visitType: DS.attr(),
vitals: DS.hasMany('vital', { async: true }),
reports: DS.hasMany('report', { async: true }),

diagnosisList: computed('diagnoses.[]', function() {
let diagnoses = this.get('diagnoses');
Expand Down
Loading

0 comments on commit 88073bc

Please sign in to comment.