...
 
Commits (68)
import EmberObject, { computed } from '@ember/object';
import { inject as service } from '@ember/service';
import { isEmpty, compare } from '@ember/utils';
import AbstractEditController from 'hospitalrun/controllers/abstract-edit-controller';
import uuid from 'npm:uuid';
export default AbstractEditController.extend({
customForms: service(),
preview: false,
previewModel: EmberObject.create(),
updateCapability: 'update_config',
afterUpdate() {
let customForms = this.get('customForms');
let model = this.get('model');
customForms.resetCustomFormByType(model.get('formType'));
this.displayAlert(this.get('i18n').t('admin.customForms.titles.formSaved'), this.get('i18n').t('admin.customForms.messages.formSaved', this.get('model')));
},
......
......@@ -87,6 +87,12 @@ export default Controller.extend(BillingCategories, EKMixin,
'locationsAffected' // Special use case that we need to handle
]
}
}, {
name: this.get('i18n').t('admin.lookup.enfermeros'),
value: 'enfermeros',
model: {
imaging: 'enfermero'
}
}, {
name: this.get('i18n').t('admin.lookup.warehouseList'),
value: 'warehouse_list',
......@@ -124,6 +130,13 @@ export default Controller.extend(BillingCategories, EKMixin,
models: {
pricing: 'pricingType'
}
}, {
name: this.get('i18n').t('admin.lookup.medidas'),
value: 'medidas',
model: {
imaging: 'medida',
'proc-charge': 'medida'
}
}, {
name: this.get('i18n').t('admin.lookup.patientStatusList'),
value: 'patient_status_list',
......@@ -136,6 +149,7 @@ export default Controller.extend(BillingCategories, EKMixin,
models: {
appointment: 'provider',
visit: 'examiner',
procmed: 'medico',
procedure: [
'assistant',
'physician'
......@@ -171,6 +185,18 @@ export default Controller.extend(BillingCategories, EKMixin,
model: {
patient: 'sex'
}
}, {
name: this.get('i18n').t('admin.lookup.tipoProcedimientos'),
value: 'tipoProcedimientos',
model: {
procmed: 'tipoProcedimiento'
}
}, {
name: this.get('i18n').t('admin.lookup.tipoProcedimientoEnfermerias'),
value: 'tipoProcedimientoEnfermerias',
model: {
imaging: 'tipoProcedimientoEnfermeria'
}
}, {
defaultValues: 'defaultUnitList',
name: this.get('i18n').t('admin.lookup.unitTypes'),
......@@ -287,6 +313,12 @@ export default Controller.extend(BillingCategories, EKMixin,
}
break;
}
case 'procmed_pricing_types': {
if (value === 'procmed Procedure') {
return false;
}
break;
}
case 'visit_types': {
if (value === 'Admission') {
return false;
......@@ -296,7 +328,10 @@ export default Controller.extend(BillingCategories, EKMixin,
return false;
} else if (value === 'Pharmacy') {
return false;
} else if (value === 'procmed') {
return false;
}
break;
}
}
return true;
......
......@@ -11,6 +11,10 @@ export default AbstractIndexRoute.extend({
return this.store.findAll('lookup').catch((error) => this.send('error', error));
},
afterModel(model) {
model.set('lookupType', 'anesthesia_types');
},
actions: {
deleteValue(value) {
this.controller.send('deleteValue', value);
......
......@@ -22,6 +22,7 @@ export default Controller.extend(EditPanelProps, {
'patient',
'photo',
'procedure',
'procmed',
'visit',
'vital'
],
......
......@@ -11,7 +11,7 @@ export default AbstractEditController.extend(UserRoles, UserSession, {
hideCancelButton: true,
updateCapability: 'define_user_roles',
filteredRoles: filter('userRoles', function(userRole) {
return (userRole.name !== 'System Administrator');
return (userRole.name !== 'Administrador de Sistema');
}),
availableCapabilities: [{
......@@ -101,6 +101,14 @@ export default AbstractEditController.extend(UserRoles, UserSession, {
'completeImaging',
'deleteImaging'
]
}, {
name: 'procmed',
capabilities: [
'procmed',
'addprocmed',
'completeprocmed',
'deleteprocmed'
]
}, {
name: 'incident',
capabilities: [
......
......@@ -16,7 +16,8 @@ export default AbstractEditRoute.extend({
followupPrepayment: false,
outpatientLabPrepayment: false,
outpatientImagingPrepayment: false,
outpatientMedicationPrepayment: false
outpatientMedicationPrepayment: false,
outpatientprocmedPrepayment: false
}
}));
});
......
......@@ -72,10 +72,15 @@ export default AbstractEditController.extend(AppointmentStatuses, PatientSubmodu
},
actions: {
appointmentTypeChanged() {
appointmentTypeChanged(appointmentType) {
let model = get(this, 'model');
set(model, 'appointmentType', appointmentType);
let isAdmissionAppointment = get(this, 'isAdmissionAppointment');
set(model, 'allDay', isAdmissionAppointment);
},
returnToAppointment() {
this.transitionToRoute('appointments.today');
}
}
});
......@@ -15,10 +15,16 @@ export default AbstractEditRoute.extend(AddToPatientRoute, PatientListRoute, {
newTitle: t('appointments.newTitle'),
actions: {
returnToAppointment() {
this.controller.send('returnToAppointment');
}
},
getNewData(params) {
let idParam = get(this, 'idParam');
let newData = {
appointmentType: 'Admission',
appointmentType: 'Consultorio',
allDay: true,
selectPatient: true,
startDate: new Date()
......
......@@ -51,6 +51,8 @@
{{form.select class="form-input-group col-sm-3 test-appointment-status" property="status"
label=(t 'models.appointment.labels.status') content=appointmentStatuses
}}
{{form.select class="form-input-group col-sm3 test-appointment-status" property="turnos"
label=(t 'models.appointment.label.turnos') content=appointmentTurnos}}
</div>
{{/if}}
{{expand-text label=(t 'models.appointment.labels.notes') property="notes" rows=3 form=form}}
......
import { A, isArray } from '@ember/array';
import { get, set, computed } from '@ember/object';
import { isEmpty } from '@ember/utils';
import { all, resolve } from 'rsvp';
import AbstractPagedController from 'hospitalrun/controllers/abstract-paged-controller';
import AddNewPatient from 'hospitalrun/mixins/add-new-patient';
import ChargeActions from 'hospitalrun/mixins/charge-actions';
import DiagnosisActions from 'hospitalrun/mixins/diagnosis-actions';
import FilterList from 'hospitalrun/mixins/filter-list';
import ModalHelper from 'hospitalrun/mixins/modal-helper';
import PatientNotes from 'hospitalrun/mixins/patient-notes';
import PatientSubmodule from 'hospitalrun/mixins/patient-submodule';
import PatientVisits from 'hospitalrun/mixins/patient-visits';
import UserSession from 'hospitalrun/mixins/user-session';
export default AbstractPagedController.extend(UserSession, {
import VisitStatus from 'hospitalrun/utils/visit-statuses';
export default AbstractPagedController.extend(AddNewPatient, ChargeActions, DiagnosisActions, FilterList, ModalHelper, PatientNotes, PatientSubmodule, PatientVisits, UserSession, VisitStatus, {
additionalModels: [{
name: 'diagnosisList',
findArgs: ['lookup', 'diagnosis_list']
}],
allowAddDiagnosis: computed.not('model.isNew'),
diagnosisList: computed.alias('visitsController.diagnosisList'),
lookupListsToUpdate: [{
name: 'diagnosisList',
property: 'model.diagnosis',
id: 'diagnosis_list'
}],
startKey: [],
updateCapability: 'add_diagnosis',
actions: {
confi(appointment) {
let i18n = this.get('i18n');
let patientDetails = i18n.t('visit.titles.conficita');
let confirmMessage = i18n.t('visit.messages.conficita');
this.displayConfirm(patientDetails, confirmMessage, 'pasamano', appointment);
},
pasamano(appointment) {
if (appointment) {
let outPatient = false;
let visitStatus;
let visitType = appointment.get('appointmentType');
if (visitType === 'Admission') {
visitStatus = VisitStatus.ADMITTED;
} else {
outPatient = true;
visitStatus = VisitStatus.CHECKED_IN;
}
let customForms = this.get('customForms');
let diagnoses = appointment.get('diagnoses');
let medico = appointment.get('provider');
let numContacto = appointment.get('location');
let patient = appointment.get('patient');
let startDate = new Date();
let turnos = appointment.get('turnos');
let newVisit = this.get('store').createRecord('visit');
resolve(appointment);
newVisit.setProperties({ outPatient, status: visitStatus });
newVisit.set('appointment', appointment);
newVisit.set('customForms', customForms);
newVisit.set('diagnoses', diagnoses);
newVisit.set('examiner', medico);
newVisit.set('hasAppointment', true);
newVisit.set('location', numContacto);
newVisit.set('patient', patient);
newVisit.set('startDate', startDate);
newVisit.set('turnos', turnos);
newVisit.set('visitType', visitType);
newVisit.save();
}
let skipAfterUpdate = true;
appointment.set('status', 'Atendido');
appointment.save();
this.saveModel(skipAfterUpdate);
}
},
saveModel(skipAfterUpdate) {
return get(this, 'model').save().then((record) => {
this.updateLookupLists().then(() => {
if (!skipAfterUpdate) {
this.afterUpdate(record);
}
});
}).catch((error) => {
this.send('error', error);
});
},
updateLookupLists() {
let lookupListsToUpdate = get(this, 'lookupListsToUpdate');
let listsToUpdate = A();
let lookupPromises = [];
if (!isEmpty(lookupListsToUpdate)) {
lookupListsToUpdate.forEach((list) => {
let propertyValue = get(this, get(list, 'property'));
let lookupListToUpdate = get(this, get(list, 'name'));
if (!isEmpty(propertyValue)) {
if (!isEmpty(lookupListToUpdate) && lookupListToUpdate.then) {
lookupPromises.push(lookupListToUpdate.then((lookupList) => {
return this._checkListForUpdate(list, lookupList, listsToUpdate, propertyValue);
}));
} else {
this._checkListForUpdate(list, lookupListToUpdate, lookupListToUpdate, propertyValue);
}
}
});
if (!isEmpty(lookupPromises)) {
return all(lookupPromises).then(() => {
let lookupLists = get(this, 'lookupLists');
let updatePromises = [];
listsToUpdate.forEach((list) => {
updatePromises.push(list.save().then(() => {
set(this, 'lookupListsLastUpdate', new Date.getTime());
lookupLists.resetLookupLists(get(list, 'id'));
}));
});
return all(updatePromises);
});
}
}
return resolve();
},
_checkListForUpdate(listInfo, lookupList, listsToUpdate, propertyValue) {
let store = get(this, 'store');
if (!lookupList) {
lookupList = store.push(store.normalize('lookup', { id: listInfo.id, value: [], userCanAdd: true }));
}
if (isArray(propertyValue)) {
propertyValue.forEach(function(value) {
this._addValueToLookupList(lookupList, value, listsToUpdate, listInfo.name);
}.bind(this));
} else {
this._addValueToLookupList(lookupList, propertyValue, listsToUpdate, listInfo.name);
}
return lookupList;
},
canAddVisit: function() {
return this.currentUserCan('add_visit');
}.property(),
......
......@@ -5,6 +5,12 @@ import { translationMacro as t } from 'ember-i18n';
export default AbstractIndexRoute.extend({
editReturn: 'appointments.index',
addCapability: 'add_visit',
additionalModels: [{
name: 'diagnosisList',
findArgs: ['lookup', 'diagnosis_list']
}],
itemsPerPage: null, // Fetch all incidents as one page
modelName: 'appointment',
newButtonText: computed('i18n.locale', () => {
return t('appointments.buttons.newButton');
......@@ -42,7 +48,7 @@ export default AbstractIndexRoute.extend({
startkey: [startOfWeek, null, null],
endkey: [endOfWeek, endOfWeek, maxId]
},
mapReduce: 'appointments_by_date'
mapReduce: 'appointments_by_date' // el mapreduce original era 'appointments_by_lastModified' se debe ver si este hace lo mismo
};
},
......@@ -50,6 +56,10 @@ export default AbstractIndexRoute.extend({
editAppointment(appointment) {
appointment.set('returnTo', this.get('editReturn'));
this.send('editItem', appointment);
},
pasamano(appointment) {
this.controller.send('pasamano', appointment);
}
}
});
......@@ -3,10 +3,12 @@
<tr class="table-header">
<th>{{t 'models.appointment.labels.appointmentDate'}}</th>
<th>{{t 'models.patient.labels.name'}}</th>
<th>{{t 'models.appointment.labels.contactNumber'}}</th>
<th>{{t 'models.appointment.labels.type'}}</th>
<th>{{t 'models.appointment.labels.location'}}</th>
<th>{{t 'models.appointment.labels.provider'}}</th>
<th>{{t 'models.appointment.labels.status'}}</th>
<th>{{t 'models.appointment.labels.turn'}}</th>
<th>{{t 'labels.actions'}}</th>
</tr>
{{#each model as |appointment|}}
......
......@@ -3,19 +3,21 @@
{{appointment.formattedAppointmentDate}}
</td>
<td>{{appointment.patient.displayName}}</td>
<td class="appointment-type">{{appointment.displayTiposCita}}</td>
<td>{{appointment.appointmentType}}</td>
<td>{{appointment.location}}</td>
<td>{{appointment.provider}}</td>
<td class="appointment-status">{{appointment.displayStatus}}</td>
<td class="appointment-turnos">{{appointment.displayTurnos}}</td>
<td>
{{#if canEdit}}
<button class="btn btn-default neutral" {{action 'editAppointment' appointment bubbles=false }}>{{t 'labels.edit'}}</button>
{{/if}}
{{#if canAddVisit}}
{{#if (eq appointment.displayStatus 'Scheduled')}}
<button class="btn btn-primary" {{action 'checkIn' appointment bubbles=false }}>
{{#if (eq appointment.displayStatus 'Agendada')}}
<button class="btn btn-primary" {{action 'confi' appointment bubbles=false }}>
<span class="glyphicon glyphicon-log-in"></span>
{{t 'visits.buttons.checkIn'}}
{{t 'visits.buttons.facturar'}}
</button>
{{/if}}
{{/if}}
......
import AppointmentIndexController from 'hospitalrun/appointments/index/controller';
export default AppointmentIndexController.extend({
startKey: []
});
\ No newline at end of file
import AppointmentIndexRoute from 'hospitalrun/appointments/index/route';
import { translationMacro as t } from 'ember-i18n';
export default AppointmentIndexRoute.extend({
editReturn: 'appointments.missed',
modelName: 'appointment',
pageTitle: t('appointments.missed'),
_modelQueryParams() {
let queryParams = this._super(...arguments);
queryParams.filterBy = [{
name: 'status',
value: 'Missed'
}];
return queryParams;
}
});
\ No newline at end of file
{{partial 'appointments/index'}}
......@@ -14,7 +14,7 @@ export default AppointmentIndexController.extend(AppointmentStatuses, VisitTypes
}.property('physicians'),
provider: null,
queryParams: ['appointmentType', 'provider', 'status', 'startKey', 'startDate'],
queryParams: ['appointmentType', 'provider', 'status', 'turnos', 'startKey', 'startDate'],
selectedProvider: null,
selectedStatus: null,
sortProperties: null,
......@@ -34,6 +34,7 @@ export default AppointmentIndexController.extend(AppointmentStatuses, VisitTypes
let provider = this.get('model.selectedProvider');
let status = this.get('model.selectedStatus');
let startDate = this.get('model.selectedStartingDate');
let turnos = this.get('model.selectedTurnos');
if (isEmpty(appointmentType)) {
fieldsToSet.appointmentType = null;
......@@ -53,6 +54,11 @@ export default AppointmentIndexController.extend(AppointmentStatuses, VisitTypes
if (!isEmpty(startDate)) {
fieldsToSet.startDate = startDate.getTime();
}
if (!isEmpty(turnos)) {
fieldsToSet.turnos = null;
} else {
fieldsToSet.turnos = turnos;
}
if (!isEmpty(fieldsToSet)) {
this.setProperties(fieldsToSet);
}
......
......@@ -7,7 +7,7 @@ import { translationMacro as t } from 'ember-i18n';
export default AppointmentIndexRoute.extend(DateFormat, {
editReturn: 'appointments.search',
filterParams: ['appointmentType', 'provider', 'status'],
filterParams: ['appointmentType', 'provider', 'status', 'turnos'],
modelName: 'appointment',
pageTitle: computed('i18n.locale', () => {
return t('appointments.searchTitle');
......@@ -17,6 +17,7 @@ export default AppointmentIndexRoute.extend(DateFormat, {
appointmentType: { refreshModel: true },
provider: { refreshModel: true },
status: { refreshModel: true },
turnos: { refreshModel: true },
startDate: { refreshModel: true },
startKey: { refreshModel: true }
},
......@@ -45,7 +46,8 @@ export default AppointmentIndexRoute.extend(DateFormat, {
model.setProperties({
selectedAppointmentType: params.appointmentType,
selectedProvider: params.provider,
selectedStatus: params.status
selectedStatus: params.status,
selectedTurnos: params.turnos
});
let { startDate } = params;
startDate = new Date();
......
......@@ -14,6 +14,8 @@
{{form.select class="col-sm-3 form-input-group test-selected-provider" property="selectedProvider"
label=(t 'models.appointment.labels.provider') content=physicianList
}}
{{form.select class="col-sm-3 form-input-group test-selected-turnos" property="selectedTurnos"
label=(t 'models.appointment.label.turn') content=appointmentTurnosWithEmpty}}
</div>
{{/em-form}}
</div>
......@@ -29,6 +31,7 @@
{{#sortable-column sortBy='location' sortDesc=sortDesc sortKey=sortKey }}{{t 'models.appointment.labels.location'}}{{/sortable-column}}
{{#sortable-column sortBy='provider' sortDesc=sortDesc sortKey=sortKey }}{{t 'models.appointment.labels.provider'}}{{/sortable-column}}
{{#sortable-column sortBy='status' sortDesc=sortDesc sortKey=sortKey }}{{t 'models.appointment.labels.status'}}{{/sortable-column}}
{{#sortable-column sortBy='turnos' sortDesc=sortDesc sortKey=sortKey }}{{t 'models.appointment.labels.turn'}}{{/sortable-column}}
<th>{{t 'labels.actions'}}</th>
</tr>
{{#each model as |appointment|}}
......
import { inject as service } from '@ember/service';
import { alias } from '@ember/object/computed';
import { get } from '@ember/object';
import { run } from '@ember/runloop';
import RSVP from 'rsvp';
import BaseAuthenticator from 'ember-simple-auth/authenticators/base';
import crypto from 'npm:crypto';
......@@ -34,6 +35,20 @@ export default BaseAuthenticator.extend(MapOauthParams, OAuthHeaders, {
});
},
_getPromise(type, data) {
return new RSVP(function(resolve, reject) {
this._makeRequest(type, data).then(function(response) {
run(function() {
resolve(response);
});
}, function(xhr) {
run(function() {
reject(xhr.responseJSON || xhr.responseText);
});
});
}.bind(this));
},
_finishAuth(user, oauthConfigs) {
let database = this.get('database');
return database.setup().then(() => {
......
import EmberObject from '@ember/object';
import Component from '@ember/component';
import { alias } from '@ember/object/computed';
import { get } from '@ember/object';
import Ember from 'ember';
import SelectValues from 'hospitalrun/utils/select-values';
import CustomFormManager from 'hospitalrun/mixins/custom-form-manager';
export default Component.extend(SelectValues, CustomFormManager, {
customForms: Ember.inject.service(),
formType: null,
formsForType: null,
model: null,
openModalAction: 'openModal',
formsForSelect: alias('customForms.formsForSelect'),
formsToDisplay: alias('customForms.formsToDisplay'),
showAddButton: alias('customForms.showAddButton'),
didReceiveAttrs() {
this._super(...arguments);
this.initFormsForType();
let customForms = get(this, 'customForms');
let formType = get(this, 'formType');
let model = get(this, 'model');
customForms.setupForms(formType, model);
},
actions: {
......
......@@ -54,6 +54,10 @@ export default EmInput.extend(PikadayComponent, {
let dateProperty = this.get('originalProperty');
let displayPropertyName = `display_${dateProperty}`;
this.currentDate = alias(`model.${dateProperty}`);
this.minDate = alias('mainComponent.minDate');
this.maxDate = alias('mainComponent.maxDate');
this.showTime = alias('mainComponent.showTime');
this.yearRange = alias('mainComponent.yearRange');
this.addObserver(`model.${dateProperty}`, this, this.currentDateChangedValue);
defineProperty(this, `model.errors.${displayPropertyName}`, alias(`model.errors.${dateProperty}`));
}
......
import Component from '@ember/component';
import { get, computed } from '@ember/object';
import { inject as service } from '@ember/service';
import { isEmpty } from '@ember/utils';
export default Component.extend({
classNames: 'ps-info-group long-form',
store: service(),
i18n: service(),
canAddAllergy: null,
patient: null,
currentAllergy: false,
displayModal: false,
editAllergyAction: 'editAllergy',
patient: null,
showAddAllergyAction: 'showAddAllergy',
additionalButtons: computed('currentAllergy', function() {
let currentAllergy = this.get('currentAllergy');
let btn = this.get('i18n').t('buttons.delete');
if (currentAllergy) {
return [{
class: 'btn btn-default warning',
buttonAction: 'deleteAllergy',
buttonIcon: 'octicon octicon-x',
buttonText: btn
}];
}
}),
buttonConfirmText: computed('currentAllergy', function() {
let i18n = this.get('i18n');
let currentAllergy = this.get('currentAllergy');
if (currentAllergy) {
return i18n.t('buttons.update');
} else {
return i18n.t('buttons.add');
}
}),
closeAllergyModal() {
this.set('currentAllergy', false);
this.set('displayModal', false);
},
modalTitle: computed('currentAllergy', function() {
let currentAllergy = this.get('currentAllergy');
let i18n = this.get('i18n');
if (currentAllergy) {
return i18n.t('allergies.titles.editAllergy');
} else {
return i18n.t('allergies.titles.addAllergy');
}
}),
showAllergies: computed('canAddAllergy', 'patient.allergies.[]', {
get() {
let canAddAllergy = get(this, 'canAddAllergy');
......@@ -19,12 +62,53 @@ export default Component.extend({
}),
actions: {
editAllergy(allergy) {
this.sendAction('editAllergyAction', allergy);
cancel() {
this.closeAllergyModal();
},
createNewAllergy() {
this.sendAction('showAddAllergyAction');
},
closeModal() {
this.closeAllergyModal();
},
deleteAllergy() {
let allergy = this.get('currentAllergy');
let patient = this.get('patient');
let patientAllergies = patient.get('allergies');
allergy.destroyRecord().then(() => {
patientAllergies.removeObject(allergy);
patient.save().then(() => {
this.closeAllergyModal();
});
});
},
editAllergy(allergy) {
this.sendAction('editAllergyAction', allergy);
},
updateAllergy() {
let model = this.get('patient');
let allergyModel = this.get('currentAllergy');
if (!allergyModel) {
allergyModel = this.get('store').createRecord('allergy', {
name: this.get('name')
});
allergyModel.save().then(() => {
model.get('allergies').pushObject(allergyModel);
model.save().then(() => {
this.set('name', '');
this.closeAllergyModal();
});
});
} else {
allergyModel.save().then(() => {
this.closeAllergyModal();
});
}
}
}
});
......@@ -10,20 +10,24 @@ export default Component.extend(FilterList, UserSession, {
editImagingAction: 'editImaging',
editLabAction: 'editLab',
editMedicationAction: 'editMedication',
editProcmedAction: 'editProcmed',
filterBy: null,
filterValue: null,
newImagingAction: 'newImaging',
newLabAction: 'newLab',
newMedicationAction: 'newMedication',
newProcmedAction: 'newProcmed',
showDeleteImagingAction: 'showDeleteImaging',
showDeleteLabAction: 'showDeleteLab',
showDeleteMedicationAction: 'showDeleteMedication',
showDeleteProcmedAction: 'showDeleteProcmed',
sortKey: null,
sortDesc: false,
orderTypeFilters: computed(function() {
let i18n = this.get('i18n');
return [
i18n.t('components.patientOrders.labels.imagingOrderType').toString(),
i18n.t('components.patientOrders.labels.procmedOrderType').toString(),
i18n.t('components.patientOrders.labels.labOrderType').toString(),
i18n.t('components.patientOrders.labels.medicationOrderType').toString()
];
......@@ -41,6 +45,10 @@ export default Component.extend(FilterList, UserSession, {
return this.currentUserCan('add_medication');
}),
canAddProcmed: computed(function() {
return this.currentUserCan('add_imaging');
}),
canDeleteImaging: computed(function() {
return this.currentUserCan('delete_imaging');
}),
......@@ -53,6 +61,10 @@ export default Component.extend(FilterList, UserSession, {
return this.currentUserCan('delete_medication');
}),
canDeleteProcmed: computed(function() {
return this.currentUserCan('delete_imaging');
}),
filteredList: computed('orderList.[]', 'filterBy', 'filterValue', function() {
let filterBy = this.get('filterBy');
let filterValue = this.get('filterValue');
......@@ -61,15 +73,17 @@ export default Component.extend(FilterList, UserSession, {
return orderList;
}),
orderList: computed('visit.imaging.[]', 'visit.labs.[]', 'visit.medication.[]', function() {
orderList: computed('visit.imaging.[]', 'visit.labs.[]', 'visit.medication.[]', 'visit.procmed.[]', function() {
let i18n = this.get('i18n');
let imaging = this.get('visit.imaging');
let labs = this.get('visit.labs');
let medication = this.get('visit.medication');
let procmed = this.get('visit.procmed');
let orderList = new A();
orderList.addObjects(imaging.map((item) => {
item.set('orderType', i18n.t('components.patientOrders.labels.imagingOrderType'));
item.set('name', item.get('imagingType.name'));
// item.set('name', item.get('imagingType.name'));
item.set('name', item.get('tipoProcedimientoEnfermeria'));
item.set('dateProcessed', item.get('imagingDate'));
this._setPermissions(item, 'canAddImaging', 'canDeleteImaging');
return item;
......@@ -90,6 +104,13 @@ export default Component.extend(FilterList, UserSession, {
this._setPermissions(item, 'canAddMedication', 'canDeleteMedication');
return item;
}));
orderList.addObjects(procmed.map((item) => {
item.set('orderType', i18n.t('components.patientOrders.label.procmedOrderType'));
item.set('name', item.get('tipoProcedimiento'));
item.set('dateProcessed', item.get('procmedDate'));
this._setPermissions(item, 'canAddProcmed', 'canDeleteProcmed');
return item;
}));
return orderList;
}),
......@@ -150,6 +171,10 @@ export default Component.extend(FilterList, UserSession, {
this.sendAction('newMedicationAction');
},
newProcmed() {
this.sendAction('newProcmedAction');
},
editOrder(order) {
let modelName = order.get('constructor.modelName').capitalize();
this.sendAction(`edit${modelName}Action`, order);
......
......@@ -8,7 +8,7 @@ export default TypeAhead.extend(PatientName, {
_mapPatient(item) {
let returnObj = {};
returnObj.name = `${this.getPatientDisplayName(item)} - ${this.getPatientDisplayId(item)}`;
returnObj.name = `${this.getPatientDisplayName(item)} - ${this.getPatientDisplayId(item)} - ${this.getPatientDisplayCedula(item)} - ${this.getPatientDisplayExternalPatientId(item)}`;
returnObj[this.get('selectionKey')] = item;
return returnObj;
},
......
......@@ -20,7 +20,7 @@ export default Controller.extend(ProgressDialog, {
let currentRouteName = this.get('currentRouteName');
let currentSearchText = this.get('currentSearchText');
if (currentSearchText !== textToFind || currentRouteName.indexOf('.search') === -1) {
this.set('progressMessage', `Searching for ${textToFind}. Please wait...`);
this.set('progressMessage', `Buscando ${textToFind}. Espere por favor...`);
this.showProgressModal();
this.transitionToRoute(`${this.searchRoute}/${textToFind}`);
}
......
import { alias } from '@ember/object/computed';
import { inject as controller } from '@ember/controller';
import { isEmpty } from '@ember/utils';
import { inject as service } from '@ember/service';
import { set, get } from '@ember/object';
import Controller from '@ember/controller';
import HospitalRunVersion from 'hospitalrun/mixins/hospitalrun-version';
import ModalHelper from 'hospitalrun/mixins/modal-helper';
import ProgressDialog from 'hospitalrun/mixins/progress-dialog';
import UserSession from 'hospitalrun/mixins/user-session';
import Navigation from 'hospitalrun/mixins/navigation';
export default Controller.extend(HospitalRunVersion, ModalHelper, ProgressDialog, UserSession, Navigation, {
ajax: service(),
application: controller(),
allowSearch: false,
config: service(),
currentSearchText: null,
currentRouteName: alias('application.currentRouteName'),
progressTitle: 'Searching',
searchRoute: null,
session: service(),
syncStatus: '',
currentOpenNav: null,
actions: {
about() {
let version = get('version');
get('ajax').request('/serverinfo').then((siteInfo) => {
let message = `Version: ${version}`;
if (!isEmpty(siteInfo)) {
message += ` Site Info: ${siteInfo}`;
}
this.displayAlert(get('i18n').t('navigation.about'), message);
});
},
invalidateSession() {
let session = get('session');
if (session.get('isAuthenticated')) {
session.invalidate();
}
},
search() {
if (this.allowSearch && this.searchRoute) {
let currentRouteName = get('currentRouteName');
let currentSearchText = get('currentSearchText');
let textToFind = get('searchText');
if (currentSearchText !== textToFind || currentRouteName.indexOf('.search') === -1) {
set('searchText', '');
set('progressMessage', `Searching for ${textToFind}. Please wait...`);
this.showProgressModal();
this.transitionToRoute(`${this.searchRoute}/${textToFind}`);
}
}
},
navAction(nav) {
if (this.currentOpenNav && this.currentOpenNav.route !== nav.route) {
this.currentOpenNav.closeSubnav();
}
set('currentOpenNav', nav);
this.transitionToRoute(nav.route);
set('isShowingSettings', false);
},
toggleSettings() {
this.toggleProperty('isShowingSettings');
},
closeSettings() {
set('isShowingSettings', false);
}
}
});
\ No newline at end of file
import { inject as service } from '@ember/service';
import { get } from '@ember/object';
import Route from '@ember/routing/route';
import MapOauthParams from 'hospitalrun/mixins/map-oauth-params';
import SetupUserRole from 'hospitalrun/mixins/setup-user-role';
......@@ -9,10 +10,23 @@ export default Route.extend(MapOauthParams, SetupUserRole, {
session: service(),
model(params) {
if (params.k && params.s1 && params.s2 && params.t) {
this.get('session').authenticate('authenticator:custom', {
get('session').authenticate('authenticator:custom', {
google_auth: true,
params
});
let oauthConfigs = {
config_consumer_key: params.k,
config_consumer_secret: params.s1,
config_oauth_token: params.t,
config_token_secret: params.s2
};
return get('config').saveOauthConfigs(oauthConfigs)
.then(function() {
oauthConfigs.config_use_google_auth = true;
return get('database').setup(oauthConfigs).then(() => {
return this.setupUserRole();
});
}.bind(this));
}
}
});
......@@ -4,5 +4,6 @@
<td class="completed-by">{{imaging.completedBy}}</td>
<td class="display-name">{{imaging.patient.displayName}}</td>
<td class="type">{{imaging.imagingType.name}}</td>
<td class="type">{{imaging.tipoProcedimentoEnfermeria}}</td>
<td class="results">{{imaging.result}}</td>
<td class="notes">{{imaging.notes}}</td>
......@@ -2,5 +2,5 @@ import { translationMacro as t } from 'ember-i18n';
import ImagingIndexRoute from 'hospitalrun/imaging/index/route';
export default ImagingIndexRoute.extend({
pageTitle: t('imaging.titles.completedImaging'),
searchStatus: 'Completed'
searchStatus: 'Completado'
});
......@@ -8,6 +8,7 @@
<th>{{t 'imaging.labels.completedBy'}}</th>
<th>{{t 'labels.patient'}}</th>
<th>{{t 'labels.imagingType'}}</th>
<th>{{t 'labels.tipoProcedimientoEnfermeria'}}</th>
<th>{{t 'labels.results'}}</th>
<th>{{t 'labels.notes'}}</th>
</tr>
......
......@@ -2,6 +2,7 @@ import { alias } from '@ember/object/computed';
import { isArray } from '@ember/array';
import { isEmpty } from '@ember/utils';
import { inject as controller } from '@ember/controller';
import EmberObject from '@ember/object';
import AbstractEditController from 'hospitalrun/controllers/abstract-edit-controller';
import ChargeActions from 'hospitalrun/mixins/charge-actions';
import PatientSubmodule from 'hospitalrun/mixins/patient-submodule';
......@@ -11,6 +12,8 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
chargePricingCategory: 'Imaging',
chargeRoute: 'imaging.charge',
editController: controller('visit/edit'),
medicationList: null,
selectedImagingType: null,
canComplete: function() {
......@@ -26,7 +29,7 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
actions: {
completeImaging() {
this.set('model.status', 'Completed');
this.set('model.status', 'Completado');
this.set('model.completedBy', this.get('model').getUserName());
this.get('model').validate().then(function() {
if (this.get('model.isValid')) {
......@@ -36,21 +39,50 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
}.bind(this)).catch(function() {});
},
showAddMedication() {
let newCharge = this.get('store').createRecord('proc-charge', {
dateCharged: new Date(),
newMedicationCharge: true,
quantity: 1
});
this.send('openModal', 'imaging.medication', newCharge, 'hola');
},
showEditMedication(charge) {
let medicationList = this.get('medicationList');
let selectedMedication = medicationList.findBy('id', charge.get('medication.id'));
charge.set('itemName', selectedMedication.name);
this.send('openModal', 'imaging.medication', charge);
},
showDeleteMedication(charge) {
this.send('openModal', 'dialog', EmberObject.create({
closeModalOnConfirm: false,
confirmAction: 'deleteCharge',
title: this.get('i18n').t('imagings.titles.deleteMedicationUsed'),
message: this.get('i18n').t('imagings.message.deleteMedication'),
chargeToDelete: charge,
updateButtonAction: 'confirm',
updateButtonText: this.get('i18n').t('buttons.ok')
}));
},
/**
* Save the imaging request(s), creating multiples when user selects multiple imaging tests.
*/
update() {
// Si ya existe un registro del paciente
if (this.get('model.isNew')) {
let newImaging = this.get('model');
let selectedImagingType = this.get('selectedImagingType');
if (isEmpty(this.get('model.status'))) {
this.set('model.status', 'Requested');
this.set('model.status', 'Solicitado');
}
this.set('model.requestedBy', newImaging.getUserName());
this.set('model.requestedDate', new Date());
if (isEmpty(selectedImagingType)) {
this.saveNewPricing(this.get('model.imagingTypeName'), 'Imaging', 'model.imagingType').then(function() {
this.addChildToVisit(newImaging, 'imaging', 'Imaging').then(function() {
this.addChildToVisit(newImaging, 'imaging', 'Procedimiento Enfermeria').then(function() {
this.saveModel();
}.bind(this));
}.bind(this));
......@@ -60,13 +92,40 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
this.createMultipleRequests(pricingRecords, 'imagingType', 'imaging', 'Imaging');
} else {
this.set('model.imagingType', pricingRecords);
this.addChildToVisit(newImaging, 'imaging', 'Imaging').then(function() {
this.addChildToVisit(newImaging, 'imaging', 'Procedimiento Enfermeria').then(function() {
this.saveModel();
}.bind(this));
}
}.bind(this));
}
} else {
} else { // Edicion
if (isEmpty(this.get('model.status'))) {
let newImaging = this.get('model');
this.set('model.status', 'Solicitado');
this.set('model.requestedBy', newImaging.getUserName());
this.set('model.requestedDate', new Date());
this.set('model.imagingDate', new Date());
let selectedImagingType = this.get('selectedImagingType');
if (isEmpty(selectedImagingType)) {
this.saveNewPricing(this.get('model.imagingTypeName'), 'Imaging', 'model.imagingType').then(function() {
this.addChildToVisit(newImaging, 'imaging', 'Imaging').then(function() {
this.saveModel();
}.bind(this));
}.bind(this));
} else {
this.getSelectedPricing('selectedImagingType').then(function(pricingRecords) {
if (isArray(pricingRecords)) {
this.createMultipleRequests(pricingRecords, 'imagingType', 'imaging', 'Imaging');
} else {
this.set('model.imagingType', pricingRecords);
this.addChildToVisit(newImaging, 'imaging', 'Imaging').then(function() {
this.saveModel();
}.bind(this));
}
}.bind(this));
}
}
this.saveModel();
}
}
......@@ -87,17 +146,22 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
}.property('canComplete', 'model.isValid'),
lookupListsToUpdate: [{
name: 'radiologistList',
property: 'model.radiologist',
id: 'radiologists'
name: 'enfermeroList',
property: 'model.enfermero',
id: 'enfermeros'
}, {
name: 'tipoProcedimientoEnfermeriaList',
property: 'model.tipoProcedimientoEnfermeria',
id: 'tipoProcedimientoEnfermerias'
}],
pricingTypeForObjectType: 'Imaging Procedure',
pricingTypeForObjectType: 'Imaging imaging',
pricingTypes: alias('imagingController.imagingPricingTypes'),
tipoProcedimientoEnfermeriaList: alias('imagingController.tipoProcedimientoEnfermeriaList'),
pricingList: null, // This gets filled in by the route
radiologistList: alias('imagingController.radiologistList'),
enfermeroList: alias('imagingController.enfermeroList'),
updateCapability: 'add_imaging',
......@@ -107,7 +171,7 @@ export default AbstractEditController.extend(ChargeActions, PatientSubmodule, {
let afterDialogAction,
alertTitle,
alertMessage;
if (this.get('model.status') === 'Completed') {
if (this.get('model.status') === 'Completado') {
alertTitle = i18n.t('imaging.alerts.completedTitle');
alertMessage = i18n.t('imaging.alerts.completedMessage');
} else {
......
......@@ -22,5 +22,17 @@ export default AbstractEditRoute.extend(AddToPatientRoute, ChargeRoute, PatientL
selectPatient: true,
requestDate: moment().startOf('day').toDate()
});
},
setupController(controller, model) {
this._super(controller, model);
let medicationQuery = { key: 'medication', include_docs: true };
this.get('database').queryMainDB(medicationQuery, 'inventory_by_type').then((result) => {
let medicationList = result.rows.map((medication) => {
return medication.doc;
});
controller.set('medicationList', medicationList);
});
}
});
......@@ -43,13 +43,57 @@
</div>
{{/if}}
{{#if canComplete}}
{{select-or-typeahead form=form model=model property="radiologist"
label=(t 'imaging.labels.radiologist') list=radiologistList
{{select-or-typeahead form=form model=model property="enfermero"
label=(t 'imaging.labels.enfermero') list=enfermeroList