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

Commit

Permalink
Avoid inventory lookups when possible
Browse files Browse the repository at this point in the history
This commit denormalizes medication information on medication and
proc-charge records by making the relationship to inventory async and
adding two additional properties to the medication and proc-charge
models: medicationTitle (denormalized inventory name) and
priceOfMedication(denormalized inventory price).
Resolves #261
  • Loading branch information
jkleinsc committed Feb 9, 2016
1 parent 47e886d commit ab3cade
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 75 deletions.
93 changes: 48 additions & 45 deletions app/invoices/edit/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,20 +231,20 @@ export default AbstractEditController.extend(NumberFormat, PatientSubmodule, Pub
}.observes('model.visit'),

_addPharmacyCharge: function(charge, medicationItemName) {
var medicationItem = charge.get(medicationItemName),
price = medicationItem.get('price'),
quantity = charge.get('quantity'),
pharmacyCharges = this.get('pharmacyCharges'),
pharmacyExpenseAccount = this.get('pharmacyExpenseAccount'),
pharmacyCharge = this.store.createRecord('line-item-detail', {
return charge.getMedicationDetails(medicationItemName).then((medicationDetails) => {
let quantity = charge.get('quantity');
let pharmacyCharges = this.get('pharmacyCharges');
let pharmacyExpenseAccount = this.get('pharmacyExpenseAccount');
let pharmacyCharge = this.store.createRecord('line-item-detail', {
id: PouchDB.utils.uuid(),
name: medicationItem.get('name'),
name: medicationDetails.name,
quantity: quantity,
price: price,
price: medicationDetails.price,
department: 'Pharmacy',
expenseAccount: pharmacyExpenseAccount
});
pharmacyCharges.addObject(pharmacyCharge);
pharmacyCharges.addObject(pharmacyCharge);
});
},

_addSupplyCharge: function(charge, department) {
Expand Down Expand Up @@ -334,8 +334,9 @@ export default AbstractEditController.extend(NumberFormat, PatientSubmodule, Pub
}
}

let pharmacyChargePromises = [];
medication.forEach(function(medicationItem) {
this._addPharmacyCharge(medicationItem, 'inventoryItem');
pharmacyChargePromises.push(this._addPharmacyCharge(medicationItem, 'inventoryItem'));
}.bind(this));

this.set('wardCharges', visitCharges.map(this._mapWardCharge.bind(this)));
Expand All @@ -344,7 +345,7 @@ export default AbstractEditController.extend(NumberFormat, PatientSubmodule, Pub
var charges = procedure.get('charges');
charges.forEach(function(charge) {
if (charge.get('medicationCharge')) {
this._addPharmacyCharge(charge, 'medication');
pharmacyChargePromises.push(this._addPharmacyCharge(charge, 'medication'));
} else {
this._addSupplyCharge(charge, 'O.R.');
}
Expand Down Expand Up @@ -375,45 +376,47 @@ export default AbstractEditController.extend(NumberFormat, PatientSubmodule, Pub
}.bind(this));
}.bind(this));

lineItem = this.store.createRecord('billing-line-item', {
id: PouchDB.utils.uuid(),
name: 'Pharmacy',
category: 'Hospital Charges'
});
lineItem.get('details').addObjects(this.get('pharmacyCharges'));
lineItems.addObject(lineItem);
Ember.RSVP.all(pharmacyChargePromises).then(() => {
lineItem = this.store.createRecord('billing-line-item', {
id: PouchDB.utils.uuid(),
name: 'Pharmacy',
category: 'Hospital Charges'
});
lineItem.get('details').addObjects(this.get('pharmacyCharges'));
lineItems.addObject(lineItem);

lineItem = this.store.createRecord('billing-line-item', {
id: PouchDB.utils.uuid(),
name: 'X-ray/Lab/Supplies',
category: 'Hospital Charges'
});
lineItem.get('details').addObjects(this.get('supplyCharges'));
lineItems.addObject(lineItem);
lineItem = this.store.createRecord('billing-line-item', {
id: PouchDB.utils.uuid(),
name: 'X-ray/Lab/Supplies',
category: 'Hospital Charges'
});
lineItem.get('details').addObjects(this.get('supplyCharges'));
lineItems.addObject(lineItem);

lineItem = this.store.createRecord('billing-line-item', {
id: PouchDB.utils.uuid(),
name: 'Ward Items',
category: 'Hospital Charges'
});
lineItem.get('details').addObjects(this.get('wardCharges'));
lineItems.addObject(lineItem);
lineItem = this.store.createRecord('billing-line-item', {
id: PouchDB.utils.uuid(),
name: 'Ward Items',
category: 'Hospital Charges'
});
lineItem.get('details').addObjects(this.get('wardCharges'));
lineItems.addObject(lineItem);

lineItem = this.store.createRecord('billing-line-item', {
id: PouchDB.utils.uuid(),
name: 'Physical Therapy',
category: 'Hospital Charges'
});
lineItems.addObject(lineItem);
lineItem = this.store.createRecord('billing-line-item', {
id: PouchDB.utils.uuid(),
name: 'Physical Therapy',
category: 'Hospital Charges'
});
lineItems.addObject(lineItem);

lineItem = this.store.createRecord('billing-line-item', {
id: PouchDB.utils.uuid(),
name: 'Others/Misc',
category: 'Hospital Charges'
});
lineItems.addObject(lineItem);
lineItem = this.store.createRecord('billing-line-item', {
id: PouchDB.utils.uuid(),
name: 'Others/Misc',
category: 'Hospital Charges'
});
lineItems.addObject(lineItem);

this.send('update', true);
this.send('update', true);
});
},

_resolveVisitDescendents: function(results, childNameToResolve) {
Expand Down
2 changes: 2 additions & 0 deletions app/medication/edit/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ export default AbstractEditController.extend(InventorySelection, FulfillRequest,
this._addNewPatient();
reject('creating new patient first');
} else {
newMedication.set('medicationTitle', newMedication.get('inventoryItem.name'));
newMedication.set('priceOfMedication', newMedication.get('inventoryItem.price'));
newMedication.set('status', 'Requested');
newMedication.set('requestedBy', newMedication.getUserName());
newMedication.set('requestedDate', new Date());
Expand Down
2 changes: 1 addition & 1 deletion app/medication/edit/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
{{#if isFulfilledOrRequested}}
<div class="form-group">
<label class="control-label">Medication</label>
<p class="form-control-static">{{model.inventoryItem.name}}</p>
<p class="form-control-static">{{model.medicationName}}</p>
</div>
{{else}}
{{inventory-typeahead property="inventoryItemTypeAhead" label="Medication" content=medicationList selection=selectedInventoryItem class="required test-medication-input"}}
Expand Down
2 changes: 1 addition & 1 deletion app/medication/index/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<tr {{action 'editItem' medicationRequest}}>
<td>{{date-format medicationRequest.prescriptionDate}}</td>
<td>{{medicationRequest.patient.displayName}}</td>
<td>{{medicationRequest.inventoryItem.name}}</td>
<td>{{medicationRequest.medicationName}}</td>
<td>{{medicationRequest.quantity}}</td>
<td>{{medicationRequest.status}}</td>
{{#if showActions}}
Expand Down
49 changes: 49 additions & 0 deletions app/mixins/medication-details.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import Ember from 'ember';
import DS from 'ember-data';
export default Ember.Mixin.create({
// Denormalized medication details so that inventory records do not need to be retrieved
getMedicationName: function(inventoryAttribute) {
let medicationTitle = this.get('medicationTitle');
if (!Ember.isEmpty(medicationTitle)) {
return medicationTitle;
} else {
this.get(inventoryAttribute).then((inventoryItem) => {
this.set('medicationTitle', inventoryItem.get('name'));
});
}
},

getMedicationPrice: function(inventoryAttribute) {
let priceOfMedication = this.get('priceOfMedication');
if (!Ember.isEmpty(priceOfMedication)) {
return priceOfMedication;
} else {
this.get(inventoryAttribute).then((inventoryItem) => {
this.set('priceOfMedication', inventoryItem.get('price'));
});
}
},

getMedicationDetails: function(inventoryAttribute) {
return new Ember.RSVP.Promise((resolve) => {
let medicationTitle = this.get('medicationTitle');
let priceOfMedication = this.get('priceOfMedication');
if (!Ember.isEmpty(medicationTitle) && !Ember.isEmpty(priceOfMedication)) {
resolve({
name: medicationTitle,
price: priceOfMedication
});
} else {
this.get(inventoryAttribute).then((inventoryItem) => {
resolve({
name: inventoryItem.get('name'),
price: inventoryItem.get('price')
});
});
}
});
},

medicationTitle: DS.attr('string'),
priceOfMedication: DS.attr('number')
});
13 changes: 11 additions & 2 deletions app/models/medication.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import CanEditRequested from 'hospitalrun/mixins/can-edit-requested';
import DS from 'ember-data';
import DateFormat from 'hospitalrun/mixins/date-format';
import Ember from 'ember';
import MedicationDetails from 'hospitalrun/mixins/medication-details';

export default AbstractModel.extend(CanEditRequested, DateFormat, {
export default AbstractModel.extend(CanEditRequested, DateFormat, MedicationDetails, {
inventoryItem: DS.belongsTo('inventory', {
async: false
async: true
}),
notes: DS.attr('string'),
patient: DS.belongsTo('patient', {
Expand All @@ -28,6 +29,14 @@ export default AbstractModel.extend(CanEditRequested, DateFormat, {
return (status === 'Requested');
}.property('status'),

medicationName: function() {
return this.getMedicationName('inventoryItem');
}.property('medicationTitle', 'inventoryItem'),

medicationPrice: function() {
return this.getMedicationPrice('inventoryItem');
}.property('priceOfMedication', 'inventoryItem'),

prescriptionDateAsTime: function() {
return this.dateToTime(this.get('prescriptionDate'));
}.property('prescriptionDate'),
Expand Down
24 changes: 16 additions & 8 deletions app/models/proc-charge.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import AbstractModel from 'hospitalrun/models/abstract';
import DS from 'ember-data';
import Ember from 'ember';
import MedicationDetails from 'hospitalrun/mixins/medication-details';

/**
* Procedure charges
*/
export default AbstractModel.extend({
export default AbstractModel.extend(MedicationDetails, {
medication: DS.belongsTo('inventory', {
async: false
}),
Expand All @@ -16,15 +17,22 @@ export default AbstractModel.extend({
dateCharged: DS.attr('date'),

medicationCharge: function() {
var medication = this.get('medication'),
let medicationTitle = this.get('medicationTitle');
if (!Ember.isEmpty(medicationTitle)) {
return true;
}
var pricingItem = this.get('pricingItem'),
newMedicationCharge = this.get('newMedicationCharge');
return (!Ember.isEmpty(medication) || newMedicationCharge);
}.property('medication'),
return (Ember.isEmpty(pricingItem) || newMedicationCharge);
}.property('medicationTitle', 'pricingItem', 'newMedicationCharge'),

medicationName: function() {
return this.getMedicationName('medication');
}.property('medicationTitle', 'medication'),

inventoryItemChanged: function() {
var inventoryItem = this.get('inventoryItem');
this.set('medication', inventoryItem);
}.observes('inventoryItem'),
medicationPrice: function() {
return this.getMedicationPrice('medication');
}.property('priceOfMedication', 'medication'),

validations: {
itemName: {
Expand Down
2 changes: 1 addition & 1 deletion app/patients/medication/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{{#each patientMedications as |medication|}}
<tr {{action "editMedication" medication}}>
<td>{{date-format medication.prescriptionDate}}</td>
<td>{{medication.inventoryItem.name}}</td>
<td>{{medication.medicationName}}</td>
<td>{{medication.status}}</td>
<td>{{medication.prescription}}</td>
<td>{{medication.requestedBy}}</td>
Expand Down
2 changes: 1 addition & 1 deletion app/procedures/edit/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
{{#each model.charges as |charge|}}
{{#if charge.medicationCharge}}
<tr>
<td>{{charge.medication.name}}</td>
<td>{{charge.medicationName}}</td>
<td>{{charge.quantity}}</td>
<td>
{{#if canAddCharge}}
Expand Down
14 changes: 5 additions & 9 deletions app/procedures/medication/controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@ export default AbstractEditController.extend(InventorySelection, {

updateCapability: 'add_charge',

medicationChanged: function() {
var model = this.get('model'),
itemName = model.get('itemName'),
medication = model.get('medication');
if (!Ember.isEmpty(medication) && medication.get('name') !== itemName) {
model.set('itemName', medication.get('name'));
}
}.observes('model.medication'),

title: function() {
var isNew = this.get('model.isNew');
if (isNew) {
Expand All @@ -31,6 +22,11 @@ export default AbstractEditController.extend(InventorySelection, {
var isNew = this.get('model.isNew');
if (isNew) {
this.set('newCharge', true);
let model = this.get('model');
let inventoryItem = model.get('inventoryItem');
model.set('medication', inventoryItem);
model.set('medicationTitle', inventoryItem.get('name'));
model.set('priceOfMedication', inventoryItem.get('price'));
}
return Ember.RSVP.Promise.resolve();
},
Expand Down
14 changes: 7 additions & 7 deletions tests/fixtures/billing.txt

Large diffs are not rendered by default.

0 comments on commit ab3cade

Please sign in to comment.