Binding Drug Frequency with Treatment Chart
- Priyanka Saxena
- Gurpreet Luthra
- Rahul De
Purpose and benefits
This config enables a user to add custom drug frequencies, like Monday, Wednesday, Friday, in Medication. The user can also configure the Treatment Chart where a custom display control displays information according to the customized frequency.
Steps
The treatment chart is available in the visit dashboard of an admitted patient
Configuration in visit.json
The following config is required in apps/clinical/visit.json:
"sections": { "Custom Treatment Chart": { "type": "custom", "displayOrder": 1, "config": { "title": "Custom Treatment Chart", "template": "<custom-treatment-chart config=config visit-summary=visitSummary></custom-treatment-chart>", "showOtherActive": true, "frequenciesToBeHandled": [ "Monday, Wednesday, Friday", "Tuesday, Thursday, Saturday", "Monday, Sunday, Wednesday" ] } }, "Treatments": { "type": "treatment", "title": "Treatments", "displayOrder": 6, "config": { "translationKey": "VISIT_TITLE_TREATMENTS_KEY", "showFlowSheet": false, "showListView": true, "showOtherActive": false, "showDetailsButton": true, "showRoute": true, "showDrugForm": true, "showProvider" : true } } }
Configuration in customControl.js
In apps/customDisplayControl/js/customControl.js (if this file is not there in js directory, create it)
If customControl.js is already present, then add this config in the end and do not merge it with any other directive.
.directive('customTreatmentChart', ['appService', 'treatmentConfig', 'treatmentService', 'spinner', '$q', function(appService, treatmentConfig, treatmentService, spinner, $q) { var link = function($scope) { var Constants = Bahmni.Clinical.Constants; var days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ]; $scope.contentUrl = appService.configBaseUrl() + "/customDisplayControl/views/customTreatmentChart.html"; $scope.atLeastOneDrugForDay = function(day) { var atLeastOneDrugForDay = false; $scope.ipdDrugOrders.getIPDDrugs().forEach(function(drug) { if (drug.isActiveOnDate(day.date)) { atLeastOneDrugForDay = true; } }); return atLeastOneDrugForDay; }; $scope.getVisitStopDateTime = function() { return $scope.visitSummary.stopDateTime || Bahmni.Common.Util.DateUtil.now(); }; $scope.getStatusOnDate = function(drug, date) { var activeDrugOrders = _.filter(drug.orders, function(order) { if ($scope.config.frequenciesToBeHandled.indexOf(order.getFrequency()) !== -1) { return getStatusBasedOnFrequency(order, date); } else { return drug.getStatusOnDate(date) === 'active'; } }); if (activeDrugOrders.length === 0) { return 'inactive'; } if (_.every(activeDrugOrders, function(order) { return order.getStatusOnDate(date) === 'stopped'; })) { return 'stopped'; } return 'active'; }; var getStatusBasedOnFrequency = function(order, date) { var activeBetweenDate = order.isActiveOnDate(date); var frequencies = order.getFrequency().split(",").map(function(day) { return day.trim(); }); var dayNumber = moment(date).day(); return activeBetweenDate && frequencies.indexOf(days[dayNumber]) !== -1; }; var init = function() { var getToDate = function() { return $scope.visitSummary.stopDateTime || Bahmni.Common.Util.DateUtil.now(); }; var programConfig = appService.getAppDescriptor().getConfigValue("program") || {}; var startDate = null, endDate = null, getEffectiveOrdersOnly = false; if (programConfig.showDetailsWithinDateRange) { startDate = $stateParams.dateEnrolled; endDate = $stateParams.dateCompleted; if (startDate || endDate) { $scope.config.showOtherActive = false; } getEffectiveOrdersOnly = true; } return $q.all([treatmentConfig(), treatmentService.getPrescribedAndActiveDrugOrders($scope.config.patientUuid, $scope.config.numberOfVisits, $scope.config.showOtherActive, $scope.config.visitUuids || [], startDate, endDate, getEffectiveOrdersOnly)]) .then(function(results) { var config = results[0]; var drugOrderResponse = results[1].data; var createDrugOrderViewModel = function(drugOrder) { return Bahmni.Clinical.DrugOrderViewModel.createFromContract(drugOrder, config); }; for (var key in drugOrderResponse) { drugOrderResponse[key] = drugOrderResponse[key].map(createDrugOrderViewModel); } var groupedByVisit = _.groupBy(drugOrderResponse.visitDrugOrders, function(drugOrder) { return drugOrder.visit.startDateTime; }); var treatmentSections = []; for (var key in groupedByVisit) { var values = Bahmni.Clinical.DrugOrder.Util.mergeContinuousTreatments(groupedByVisit[key]); treatmentSections.push({ visitDate: key, drugOrders: values }); } if (!_.isEmpty(drugOrderResponse[Constants.otherActiveDrugOrders])) { var mergedOtherActiveDrugOrders = Bahmni.Clinical.DrugOrder.Util.mergeContinuousTreatments(drugOrderResponse[Constants.otherActiveDrugOrders]); treatmentSections.push({ visitDate: Constants.otherActiveDrugOrders, drugOrders: mergedOtherActiveDrugOrders }); } $scope.treatmentSections = treatmentSections; if ($scope.visitSummary) { $scope.ipdDrugOrders = Bahmni.Clinical.VisitDrugOrder.createFromDrugOrders(drugOrderResponse.visitDrugOrders, $scope.visitSummary.startDateTime, getToDate()); } }); }; spinner.forPromise(init()); }; return { restrict: 'E', link: link, scope: { config: "=", visitSummary: '=' }, template: '<ng-include src="contentUrl"/>' } }]);
Configuration related to Views
In apps/customDislayControl/views create a HTML file and name it "customTreatmentChart.html" and add the below config in it.
<section class="block ipd-treatment-section" ng-if="::visitSummary.isAdmitted() && !print"> <h2 class="section-title">{{config.title}}</h2> <table class="h-scroll"> <thead> <tr> <th> <span>{{::(visitSummary.startDateTime | bahmniDate) + ' - '+ (getVisitStopDateTime() | bahmniDate)}}</span> </th> <th ng-repeat="drug in ::ipdDrugOrders.getIPDDrugs()" class="drug" ng-class="{active: drug.isActive()}">{{drug.orders[0].getDisplayName()}}</th> </tr> </thead> <tbody> <tr ng-repeat="day in ::ipdDrugOrders.ipdDrugSchedule.days" ng-if="atLeastOneDrugForDay(day)"> <td> <span> <!-- D{{day.dayNumber}} ({{day.date | bahmniDate}}) --> {{day.date | bahmniDate}} </span> </td> <td ng-switch="getStatusOnDate(drug, day.date)" ng-repeat="drug in ::ipdDrugOrders.ipdDrugSchedule.drugs"> <span class="fa fa-ok" ng-switch-when="active"></span> <span class="fa fa-stop" ng-switch-when="stopped"></span> </td> </tr> </tbody> </table> </section>
Configuration in OpenMRS
In OpenMRS, add a concept of class frequency and datatype N/A. As seen in screenshot below, the concept name is: "Monday, Wednesday, Friday". This is because the Bahmni UI shows this concept name on the UI for selection of "frequency", and hence should be easy to understand.
In OpenMRS DB, insert a row in order_frequency table with the concept ID of the concept created above to see the frequency in the frequency drop down of Medication tab.
The Bahmni documentation is licensed under Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)