diff --git a/app/controllers/abstract-edit-controller.js b/app/controllers/abstract-edit-controller.js
index 8e547bc0a2..003d9cc6d5 100644
--- a/app/controllers/abstract-edit-controller.js
+++ b/app/controllers/abstract-edit-controller.js
@@ -107,12 +107,7 @@ export default Ember.ObjectController.extend(IsUpdateDisabled, ModalHelper, User
*/
update: function(skipAfterUpdate) {
this.beforeUpdate().then(function() {
- this.get('model').save().then(function(record){
- this.updateLookupLists();
- if (!skipAfterUpdate) {
- this.afterUpdate(record);
- }
- }.bind(this));
+ this.saveModel(skipAfterUpdate);
}.bind(this));
}
},
@@ -130,7 +125,21 @@ export default Ember.ObjectController.extend(IsUpdateDisabled, ModalHelper, User
*/
beforeUpdate: function() {
return Ember.RSVP.Promise.resolve();
- },
+ },
+
+ /**
+ * Save the model and then (optionally) run the after update.
+ * @param skipAfterUpdate boolean (optional) indicating whether or not
+ * to skip the afterUpdate call.
+ */
+ saveModel: function(skipAfterUpdate) {
+ this.get('model').save().then(function(record){
+ this.updateLookupLists();
+ if (!skipAfterUpdate) {
+ this.afterUpdate(record);
+ }
+ }.bind(this));
+ },
/**
* Update any new values added to a lookup list
diff --git a/app/imaging/edit/controller.js b/app/imaging/edit/controller.js
index 7282b589d5..a5c8f6750e 100644
--- a/app/imaging/edit/controller.js
+++ b/app/imaging/edit/controller.js
@@ -9,8 +9,13 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
chargeRoute: 'imaging.charge',
canComplete: function() {
- return this.currentUserCan('complete_imaging');
- }.property(),
+ var imagingTypeName = this.get('selectedImagingType');
+ if (Ember.isArray(imagingTypeName) && imagingTypeName.length >1) {
+ return false;
+ } else {
+ return this.currentUserCan('complete_imaging');
+ }
+ }.property('selectedImagingType.[]'),
actions: {
completeImaging: function() {
@@ -20,7 +25,42 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
this.set('imagingDate', new Date());
this.send('update');
}
- }
+ },
+
+ /**
+ * Save the imaging request(s), creating multiples when user selects multiple imaging tests.
+ */
+ update: function() {
+ if (this.get('isNew')) {
+ var newImaging = this.get('model'),
+ selectedImagingType = this.get('selectedImagingType');
+ if (Ember.isEmpty(this.get('status'))) {
+ this.set('status', 'Requested');
+ }
+ this.set('requestedBy', newImaging.getUserName());
+ this.set('requestedDate', new Date());
+ if (Ember.isEmpty(selectedImagingType)) {
+ this.saveNewPricing(this.get('imagingTypeName'), 'Imaging','imagingType').then(function() {
+ this.addChildToVisit(newImaging, 'imaging', 'Imaging').then(function() {
+ this.saveModel();
+ }.bind(this));
+ }.bind(this));
+ } else {
+ this.getSelectedPricing('selectedImagingType').then(function(pricingRecords) {
+ if (Ember.isArray(pricingRecords)) {
+ this.createMultipleRequests(pricingRecords, 'imagingType','imaging', 'Imaging');
+ } else {
+ this.set('imagingType', pricingRecords);
+ this.addChildToVisit(newImaging, 'imaging', 'Imaging').then(function() {
+ this.saveModel();
+ }.bind(this));
+ }
+ }.bind(this));
+ }
+ } else {
+ this.saveModel();
+ }
+ }
},
additionalButtons: function() {
@@ -49,30 +89,12 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
radiologistList: Ember.computed.alias('controllers.imaging.radiologistList'),
- imagingTypeChanged: function() {
- this.objectTypeChanged('imagingTypeName', 'imagingType');
- }.observes('imagingType'),
-
- imagingTypeNameChanged: function() {
- this.objectTypeNameChanged('imagingTypeName', 'selectedImagingType');
- }.observes('imagingTypeName'),
-
- showCharges: function() {
- var imagingType = this.get('imagingType'),
- patient = this.get('patient'),
- visit = this.get('visit');
- return (!Ember.isEmpty(imagingType) && !Ember.isEmpty(patient) &&
- !Ember.isEmpty(visit));
- }.property('imagingType','patient', 'visit'),
-
updateCapability: 'add_imaging',
- selectedImagingTypeChanged: function() {
- this.selectedObjectTypeChanged('selectedImagingType', 'imagingType');
- }.observes('selectedImagingType'),
-
- afterUpdate: function() {
- var alertTitle,
+ afterUpdate: function(saveResponse, multipleRecords) {
+ this.updateLookupLists();
+ var afterDialogAction,
+ alertTitle,
alertMessage;
if (this.get('status') === 'Completed') {
alertTitle = 'Imaging Request Completed';
@@ -81,33 +103,11 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
alertTitle = 'Imaging Request Saved';
alertMessage = 'The imaging request has been saved.';
}
- this.saveVisitIfNeeded(alertTitle, alertMessage);
- this.set('selectPatient', false);
- },
-
- beforeUpdate: function() {
- if (!this.get('isValid')) {
- return Ember.RSVP.reject();
+ if (multipleRecords) {
+ afterDialogAction = 'allItems';
}
- return new Ember.RSVP.Promise(function(resolve, reject) {
- this.updateCharges().then(function() {
- if (this.get('isNew')) {
- var newImaging = this.get('model');
- this.set('status', 'Requested');
- this.set('requestedBy', newImaging.getUserName());
- this.set('requestedDate', new Date());
- if (this.get('newObjectType')) {
- this.saveNewPricing(this.get('imagingTypeName'), 'Imaging','imagingType').then(function() {
- this.addChildToVisit(newImaging, 'imaging', 'Imaging').then(resolve, reject);
- }.bind(this), reject);
- } else {
- return this.addChildToVisit(newImaging, 'imaging', 'Imaging').then(resolve, reject);
- }
- } else {
- resolve();
- }
- }.bind(this), reject);
- }.bind(this), 'beforeUpdate on imaging edit');
+ this.saveVisitIfNeeded(alertTitle, alertMessage, afterDialogAction);
+ this.set('selectPatient', false);
}
});
\ No newline at end of file
diff --git a/app/imaging/edit/template.hbs b/app/imaging/edit/template.hbs
index 6745408d30..d8a8a6ec8d 100644
--- a/app/imaging/edit/template.hbs
+++ b/app/imaging/edit/template.hbs
@@ -3,37 +3,37 @@
{{patient-typeahead property="patientTypeAhead" label="Patient" content=patientList selection=selectedPatient class="required"}}
{{else}}
{{patient-summary patient=patient returnTo='imaging.edit' returnToContext=id disablePatientLink=isNew }}
- {{/if}}
-
- {{#if isNew}}
+ {{/if}}
+ {{#if isNew}}
+
{{em-select class="col-xs-3 required" label="Visit"
property="visit" content=patientVisits
optionValuePath="content" optionLabelPath="content.visitDescription"
prompt="--Add New Visit--"
selected=visit
}}
- {{else}}
+
+ {{checkbox-or-typeahead property="imagingTypeName"
+ label="Imaging Type" list=objectTypeList
+ selection=selectedImagingType
+ optionLabelPath='content.name'
+ typeAheadType='pricing'
+ class="required"
+ prompt=" "
+ model=model
+ }}
+ {{else}}
+
- {{/if}}
- {{#if isNew}}
- {{select-or-typeahead property="imagingTypeName"
- label="Imaging Type" list=objectTypeList
- selection=selectedImagingType
- optionLabelPath='content.name'
- typeAheadType='pricing'
- class="required col-xs-9"
- prompt=" "
- }}
- {{else}}
- {{/if}}
-
+
+ {{/if}}
{{#if canComplete}}
{{select-or-typeahead property="radiologist"
label="Radiologist" list=radiologistList
diff --git a/app/labs/edit/controller.js b/app/labs/edit/controller.js
index 0076626ad1..5d52b8b457 100644
--- a/app/labs/edit/controller.js
+++ b/app/labs/edit/controller.js
@@ -10,8 +10,13 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
canComplete: function() {
- return this.currentUserCan('complete_lab');
- }.property(),
+ var labTypeName = this.get('selectedLabType');
+ if (Ember.isArray(labTypeName) && labTypeName.length >1) {
+ return false;
+ } else {
+ return this.currentUserCan('complete_lab');
+ }
+ }.property('selectedLabType.[]'),
actions: {
completeLab: function() {
@@ -21,6 +26,41 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
this.set('labDate', new Date());
this.send('update');
}
+ },
+
+ /**
+ * Update the model and perform the before update and after update
+ */
+ update: function() {
+ if (this.get('isNew')) {
+ var newLab = this.get('model'),
+ selectedLabType = this.get('selectedLabType');
+ if (Ember.isEmpty(this.get('status'))) {
+ this.set('status', 'Requested');
+ }
+ this.set('requestedBy', newLab.getUserName());
+ this.set('requestedDate', new Date());
+ if (Ember.isEmpty(selectedLabType)) {
+ this.saveNewPricing(this.get('labTypeName'), 'Lab', 'labType').then(function() {
+ this.addChildToVisit(newLab, 'labs', 'Lab').then(function() {
+ this.saveModel();
+ }.bind(this));
+ }.bind(this));
+ } else {
+ this.getSelectedPricing('selectedLabType').then(function(pricingRecords) {
+ if (Ember.isArray(pricingRecords)) {
+ this.createMultipleRequests(pricingRecords, 'labType','labs', 'Lab');
+ } else {
+ this.set('labType', pricingRecords);
+ this.addChildToVisit(newLab, 'labs', 'Lab').then(function() {
+ this.saveModel();
+ }.bind(this));
+ }
+ }.bind(this));
+ }
+ } else {
+ this.saveModel();
+ }
}
},
@@ -42,30 +82,11 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
pricingList: null, //This gets filled in by the route
- labTypeChanged: function() {
- this.objectTypeChanged('labTypeName', 'labType');
- }.observes('labType'),
-
- labTypeNameChanged: function() {
- this.objectTypeNameChanged('labTypeName', 'selectedLabType');
- }.observes('labTypeName'),
-
- showCharges: function() {
- var labType = this.get('labType'),
- patient = this.get('patient'),
- visit = this.get('visit');
- return (!Ember.isEmpty(labType) && !Ember.isEmpty(patient) &&
- !Ember.isEmpty(visit));
- }.property('labType','patient', 'visit'),
-
updateCapability: 'add_lab',
- selectedLabTypeChanged: function() {
- this.selectedObjectTypeChanged('selectedLabType', 'labType');
- }.observes('selectedLabType'),
-
- afterUpdate: function() {
- var alertMessage,
+ afterUpdate: function(saveResponse, multipleRecords) {
+ var afterDialogAction,
+ alertMessage,
alertTitle;
if (this.get('status') === 'Completed') {
alertTitle = 'Lab Request Completed';
@@ -74,32 +95,11 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
alertTitle = 'Lab Request Saved';
alertMessage = 'The lab request has been saved.';
}
- this.saveVisitIfNeeded(alertTitle, alertMessage);
- },
-
- beforeUpdate: function() {
- if (!this.get('isValid')) {
- return Ember.RSVP.reject();
+ if (multipleRecords) {
+ afterDialogAction = 'allItems';
}
- return new Ember.RSVP.Promise(function(resolve, reject) {
- this.updateCharges().then(function() {
- if (this.get('isNew')) {
- var newLab = this.get('model');
- this.set('status', 'Requested');
- this.set('requestedBy', newLab.getUserName());
- this.set('requestedDate', new Date());
- if (this.get('newObjectType')) {
- this.saveNewPricing(this.get('labTypeName'), 'Lab', 'labType').then(function() {
- this.addChildToVisit(newLab, 'labs', 'Lab').then(resolve, reject);
- }.bind(this), reject);
- } else {
- return this.addChildToVisit(newLab, 'labs', 'Lab').then(resolve, reject);
- }
- } else {
- resolve();
- }
- }.bind(this), reject);
- }.bind(this), 'beforeUpdate on lab edit');
+ this.saveVisitIfNeeded(alertTitle, alertMessage, afterDialogAction);
+ this.set('selectPatient', false);
}
});
\ No newline at end of file
diff --git a/app/labs/edit/template.hbs b/app/labs/edit/template.hbs
index a9d4caafea..0b40cf1f7e 100644
--- a/app/labs/edit/template.hbs
+++ b/app/labs/edit/template.hbs
@@ -1,41 +1,41 @@
{{#em-form model=this submit_button=false }}
-
{{#if selectPatient}}
{{patient-typeahead property="patientTypeAhead" label="Patient" content=patientList selection=selectedPatient class="required"}}
{{else}}
{{patient-summary patient=patient returnTo='labs.edit' returnToContext=id disablePatientLink=isNew }}
{{/if}}
-
- {{#if isNew}}
+
+ {{#if isNew}}
+
{{em-select class="col-xs-3 required" label="Visit"
property="visit" content=patientVisits
optionValuePath="content" optionLabelPath="content.visitDescription"
prompt="--Add New Visit--"
selected=visit
}}
- {{else}}
+
+ {{checkbox-or-typeahead property="labTypeName"
+ label="Lab Type" list=objectTypeList
+ selection=selectedLabType
+ optionLabelPath='content.name'
+ typeAheadType='pricing'
+ class="required"
+ prompt=" "
+ model=model
+ }}
+ {{else}}
+
- {{/if}}
-
- {{#if isNew}}
- {{select-or-typeahead property="labTypeName"
- label="Lab Type" list=objectTypeList
- selection=selectedLabType
- optionLabelPath='content.name'
- typeAheadType='pricing'
- class="required col-xs-6"
- prompt=" "
- }}
- {{else}}
- {{/if}}
-
+
+ {{/if}}
+
{{#if canComplete}}
{{em-input property="result" label="Result"}}
{{/if}}
diff --git a/app/mixins/charge-actions.js b/app/mixins/charge-actions.js
index 14004ec4f9..f931f6c07c 100644
--- a/app/mixins/charge-actions.js
+++ b/app/mixins/charge-actions.js
@@ -88,29 +88,6 @@ export default Ember.Mixin.create({
});
return chargeForItem;
},
-
- newObjectType: false,
-
- objectTypeChanged: function(objectTypeNameField, typeField) {
- var isNew = this.get('isNew'),
- objectTypeName = this.get(objectTypeNameField),
- objectType = this.get(typeField);
- if (isNew) {
- if(objectTypeName instanceof Object) {
- this.set('newObjectType', false);
- } else {
- if (!Ember.isEmpty(objectType)) {
- this.set('newObjectType', false);
- if (objectType.get('name') !== objectTypeName) {
- this.set(objectTypeNameField, objectType.get('name'));
- }
- } else {
- this.set('newObjectType', true);
- }
- }
- }
- },
-
/**
* Returns object types out of the pricing list.
* Used for labs and imaging where the labs and imaging types are
@@ -129,15 +106,7 @@ export default Ember.Mixin.create({
}
return returnList;
}.property('pricingList','pricingTypeForObjectType','pricingTypeValues'),
-
- objectTypeNameChanged: function(objectTypeNameField, selectedField) {
- var isNew = this.get('isNew'),
- objectTypeName = this.get(objectTypeNameField);
- if (isNew && objectTypeName instanceof Object) {
- this.set(selectedField, objectTypeName);
- }
- },
-
+
organizeByType: Ember.computed.alias('pricingTypes.organizeByType'),
pricingTypeList: function() {
@@ -152,6 +121,51 @@ export default Ember.Mixin.create({
pricingTypeValues: Ember.computed.alias('pricingTypes.value'),
+ /**
+ * Create multiple new request records from the pricing records passed in. This function
+ * will also add those new records to the specified visit.
+ * @param {array} pricingRecords the list of pricing records to use to create request records from.
+ * @param {string} pricingField the name of the field on the request record to set the pricing record on.
+ * @param {string} visitChildName the name of the child object on the visit to add to.
+ * @param {string} newVisitType if a new visit needs to be created, what type of visit
+ * should be created.
+ */
+ createMultipleRequests: function(pricingRecords, pricingField, visitChildName, newVisitType) {
+ var addPromises = [],
+ attributesToSave = {},
+ baseModel = this.get('model'),
+ modelToSave,
+ patient = this.get('patient'),
+ visit = this.get('visit');
+
+ if (Ember.isEmpty(visit)) {
+ visit = this.createNewVisit(newVisitType);
+ }
+ baseModel.eachAttribute(function(name) {
+ attributesToSave[name] = baseModel.get(name);
+ });
+
+ pricingRecords.forEach(function(pricingRecord) {
+ modelToSave = this.store.createRecord(newVisitType.toLowerCase(), attributesToSave);
+ modelToSave.set(pricingField, pricingRecord);
+ modelToSave.set('patient', patient);
+ modelToSave.set('visit', visit);
+ addPromises.push(this.addChildToVisit(modelToSave, visitChildName, newVisitType));
+ }.bind(this));
+
+ Ember.RSVP.all(addPromises).then(function(results) {
+ var savePromises = [];
+ results.forEach(function(newObject) {
+ console.log("Results are:", newObject);
+ savePromises.push(newObject.save());
+ });
+ Ember.RSVP.all(savePromises).then(function(saveResponse) {
+ this.set('visit', visit); //Make sure the visit is properly set for saving
+ this.afterUpdate(saveResponse, true);
+ }.bind(this));
+ }.bind(this));
+ },
+
saveNewPricing: function(pricingName, pricingCategory, priceObjectToSet) {
return new Ember.RSVP.Promise(function(resolve, reject) {
var newPricing,
@@ -172,17 +186,21 @@ export default Ember.Mixin.create({
}.bind(this), 'saveNewPricing for: '+pricingName);
},
- selectedObjectTypeChanged: function(selectedField, typeField) {
- var isNew = this.get('isNew'),
- selectedItem = this.get(selectedField);
- if (isNew) {
- if (!Ember.isEmpty(selectedItem)) {
- this.store.find('pricing', selectedItem._id.substr(8)).then(function(item) {
- this.set(typeField, item);
- }.bind(this));
- } else {
- this.set(typeField);
- }
+ getSelectedPricing: function(selectedField) {
+ var selectedItem = this.get(selectedField);
+ if (!Ember.isEmpty(selectedItem)) {
+ return new Ember.RSVP.Promise(function(resolve, reject) {
+ if (Ember.isArray(selectedItem)) {
+ var pricingIds = selectedItem.map(function(pricingItem) {
+ return pricingItem._id.substr(8);
+ });
+ this.store.findByIds('pricing', pricingIds).then(resolve, reject);
+ } else {
+ this.store.find('pricing', selectedItem._id.substr(8)).then(resolve, reject);
+ }
+ }.bind(this));
+ } else {
+ return Ember.RSVP.resolve();
}
},
diff --git a/app/mixins/patient-submodule.js b/app/mixins/patient-submodule.js
index e9f5592407..8c985fb7d6 100644
--- a/app/mixins/patient-submodule.js
+++ b/app/mixins/patient-submodule.js
@@ -28,24 +28,16 @@ export default Ember.Mixin.create(PatientVisits, {
addChildToVisit: function(objectToAdd, childName, newVisitType) {
return new Ember.RSVP.Promise(function(resolve, reject){
var childPromises = [],
- patient = this.get('patient'),
visit = this.get('visit');
if (Ember.isEmpty(visit)) {
- visit = this.get('store').createRecord('visit', {
- startDate: new Date(),
- endDate: new Date(),
- outPatient: true,
- patient: patient,
- visitType: newVisitType
- });
- this.set('visit', visit);
+ visit = this.createNewVisit(newVisitType);
}
childPromises.addObjects(this.resolveVisitChildren());
Ember.RSVP.all(childPromises, 'Resolved visit children before adding new '+childName).then(function() {
visit.get(childName).then(function(visitChildren) {
visitChildren.addObject(objectToAdd);
this.set('needToUpdateVisit', true);
- resolve();
+ resolve(objectToAdd);
}.bind(this), reject);
}.bind(this), reject);
}.bind(this));
@@ -63,6 +55,19 @@ export default Ember.Mixin.create(PatientVisits, {
}
}.property('returnToPatient', 'returnToVisit'),
+ createNewVisit: function(newVisitType) {
+ var patient = this.get('patient'),
+ visit = this.get('store').createRecord('visit', {
+ startDate: new Date(),
+ endDate: new Date(),
+ outPatient: true,
+ patient: patient,
+ visitType: newVisitType
+ });
+ this.set('visit', visit);
+ return visit;
+ },
+
patientId: Ember.computed.alias('patient.id'),
patientChanged: function() {
@@ -143,14 +148,14 @@ export default Ember.Mixin.create(PatientVisits, {
* @param alertTitle String the title to use on the alert.
* @param alertMessage String the message to display in the alert.
*/
- saveVisitIfNeeded: function(alertTitle, alertMessage) {
+ saveVisitIfNeeded: function(alertTitle, alertMessage, alertAction) {
if (this.get('needToUpdateVisit')) {
this.get('visit').save().then(function() {
this.set('needToUpdateVisit', false);
- this.displayAlert(alertTitle, alertMessage);
+ this.displayAlert(alertTitle, alertMessage, alertAction);
}.bind(this));
} else {
- this.displayAlert(alertTitle, alertMessage);
+ this.displayAlert(alertTitle, alertMessage, alertAction);
}
},
diff --git a/app/models/imaging.js b/app/models/imaging.js
index 50dc84438e..0c513c7c5d 100644
--- a/app/models/imaging.js
+++ b/app/models/imaging.js
@@ -31,7 +31,8 @@ export default AbstractModel.extend(DateFormat, ResultValidation, {
if (object.get('isNew')) {
return true;
}
- }
+ },
+ message: 'Please select an imaging type'
}
},
patientTypeAhead: PatientValidation.patientTypeAhead,
diff --git a/app/models/lab.js b/app/models/lab.js
index 11bffe52ee..9c15dcf8ae 100644
--- a/app/models/lab.js
+++ b/app/models/lab.js
@@ -30,7 +30,8 @@ export default AbstractModel.extend(DateFormat, ResultValidation, {
if (object.get('isNew')) {
return true;
}
- }
+ },
+ message: 'Please select a lab type'
}
},
patientTypeAhead: PatientValidation.patientTypeAhead,