Binding Drug Frequency with Treatment Chart

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

Code Snippet
"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.

Code Snippet
.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.

Code Snippet
<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.

On this page