dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #38156
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 19480: Tracker rules engine now executes tracker program indicators. Added rulebound widget for showing ...
------------------------------------------------------------
revno: 19480
committer: Markus Bekken <markus.bekken@xxxxxxxxx>
branch nick: dhis2
timestamp: Mon 2015-06-22 00:18:40 +0200
message:
Tracker rules engine now executes tracker program indicators. Added rulebound widget for showing indicators in tracker capture.
modified:
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dashboard/dashboard-controller.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app.properties
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app_ar.properties
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js
dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js
dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.services.js
--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk
Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js 2015-06-18 15:15:29 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/event-capture.js 2015-06-21 22:18:40 +0000
@@ -485,7 +485,7 @@
function getProgramIndicators( programIndicators )
{
- return checkAndGetD2Objects( programIndicators, 'programIndicators', '../api/programIndicators', 'fields=id,name,code,shortName,expression,displayDescription,rootDate,description,valueType,DisplayName,program[id]');
+ return checkAndGetD2Objects( programIndicators, 'programIndicators', '../api/programIndicators', 'fields=id,name,code,shortName,expression,displayDescription,rootDate,description,valueType,DisplayName,filter,program[id]');
}
function getMetaProgramRules( programs )
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js 2015-06-18 15:15:29 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-capture/scripts/services.js 2015-06-21 22:18:40 +0000
@@ -174,55 +174,6 @@
};
})
-/* factory to fetch and process programValidations */
-.factory('MetaDataFactory', function($q, $rootScope, ECStorageService) {
-
- return {
- get: function(store, uid){
-
- var def = $q.defer();
-
- ECStorageService.currentStore.open().done(function(){
- ECStorageService.currentStore.get(store, uid).done(function(pv){
- $rootScope.$apply(function(){
- def.resolve(pv);
- });
- });
- });
- return def.promise;
- },
- getByProgram: function(store, program){
- var def = $q.defer();
- var obj = [];
-
- ECStorageService.currentStore.open().done(function(){
- ECStorageService.currentStore.getAll(store, program).done(function(pvs){
- angular.forEach(pvs, function(pv){
- if(pv.program.id === program){
- obj.push(pv);
- }
- });
- $rootScope.$apply(function(){
- def.resolve(obj);
- });
- });
- });
- return def.promise;
- },
- getAll: function(store){
- var def = $q.defer();
- ECStorageService.currentStore.open().done(function(){
- ECStorageService.currentStore.getAll(store).done(function(pvs){
- $rootScope.$apply(function(){
- def.resolve(pvs);
- });
- });
- });
- return def.promise;
- }
- };
-})
-
/* factory for handling events */
.factory('DHIS2EventFactory', function($http, $q, ECStorageService, $rootScope) {
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dashboard/dashboard-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dashboard/dashboard-controller.js 2015-06-11 18:44:52 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dashboard/dashboard-controller.js 2015-06-21 22:18:40 +0000
@@ -78,6 +78,11 @@
$rootScope.dashboardWidgets.push($rootScope.enrollmentWidget);
$scope.dashboardStatus[widget.title] = angular.copy(widget);
break;
+ case 'indicators':
+ $rootScope.indicatorWidget = widget;
+ $rootScope.dashboardWidgets.push($rootScope.indicatorWidget);
+ $scope.dashboardStatus[widget.title] = angular.copy(widget);
+ break;
case 'dataentry':
$rootScope.dataentryWidget = widget;
$rootScope.dashboardWidgets.push($rootScope.dataentryWidget);
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js 2015-06-15 15:29:59 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js 2015-06-21 22:18:40 +0000
@@ -117,10 +117,10 @@
//If the events is displayed in a table, it is necessary to run the rules for all visible events.
if($scope.currentStage.displayEventsInTable) {
angular.forEach($scope.currentStageEvents, function(event) {
- TrackerRulesExecutionService.executeRules($scope.selectedProgramId,event,$scope.eventsByStage,$scope.prStDes,$scope.selectedTei);
+ TrackerRulesExecutionService.executeRules($scope.selectedProgramId,event,$scope.eventsByStage,$scope.prStDes,$scope.selectedTei,$scope.selectedEnrollment);
});
} else {
- TrackerRulesExecutionService.executeRules($scope.selectedProgramId,$scope.currentEvent,$scope.eventsByStage,$scope.prStDes,$scope.selectedTei);
+ TrackerRulesExecutionService.executeRules($scope.selectedProgramId,$scope.currentEvent,$scope.eventsByStage,$scope.prStDes,$scope.selectedTei,$scope.selectedEnrollment);
}
};
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app.properties'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app.properties 2015-06-15 15:29:59 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app.properties 2015-06-21 22:18:40 +0000
@@ -138,6 +138,7 @@
search_from_existing=Search from existing
name=Name
dataentry=Data Entry
+indicators=Indicators
custom_form=Custom form
default_form=Default form
menu=Menu
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app_ar.properties'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app_ar.properties 2015-06-08 08:54:37 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/i18n/i18n_app_ar.properties 2015-06-21 22:18:40 +0000
@@ -114,6 +114,7 @@
search_from_existing=\u0627\u0628\u062d\u062b \u0628\u0645\u0639\u064a\u0627\u0631 \u0645\u062a\u0649 \u062a\u0645 \u0627\u0644\u0627\u0646\u0634\u0627\u0621
name=\u0627\u0633\u0645
dataentry=\u0627\u062f\u062e\u0627\u0644 \u0627\u0644\u0628\u064a\u0627\u0646\u0627\u062a
+indicators=\u0627\u0644\u0645\u0624\u0634\u0631\u0627\u062a ( \u062c\u0648\u062c\u0644 \u062a\u0631\u062c\u0645\u0629 )
custom_form=\u0627\u0633\u062a\u0645\u0627\u0631\u0629 \u0645\u062e\u0635\u0635\u0629
default_form=\u0627\u0633\u062a\u0645\u0627\u0631\u0629 \u0627\u0641\u062a\u0631\u0627\u0636\u064a\u0629
menu=\u0642\u0627\u0626\u0645\u0629
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js 2015-06-17 08:54:51 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js 2015-06-21 22:18:40 +0000
@@ -10,7 +10,7 @@
var store = new dhis2.storage.Store({
name: "dhis2tc",
adapters: [dhis2.storage.IndexedDBAdapter, dhis2.storage.DomSessionStorageAdapter, dhis2.storage.InMemoryAdapter],
- objectStores: ['programs', 'programStages', 'trackedEntities', 'trackedEntityForms', 'attributes', 'relationshipTypes', 'optionSets', 'programValidations', 'ouLevels', 'programRuleVariables', 'programRules']
+ objectStores: ['programs', 'programStages', 'trackedEntities', 'trackedEntityForms', 'attributes', 'relationshipTypes', 'optionSets', 'programValidations', 'ouLevels', 'programRuleVariables', 'programRules','constants']
});
return{
currentStore: store
@@ -22,8 +22,9 @@
var w = {};
w.enrollmentWidget = {title: 'enrollment', view: "components/enrollment/enrollment.html", show: true, expand: true, parent: 'biggerWidget', order: 0};
- w.dataentryWidget = {title: 'dataentry', view: "components/dataentry/dataentry.html", show: true, expand: true, parent: 'biggerWidget', order: 1};
- w.reportWidget = {title: 'report', view: "components/report/tei-report.html", show: true, expand: true, parent: 'biggerWidget', order: 2};
+ w.indicatorWidget = {title: 'indicators', view: "components/rulebound/rulebound.html", show: true, expand: true, parent: 'biggerWidget', order: 1, code:'indicators'};
+ w.dataentryWidget = {title: 'dataentry', view: "components/dataentry/dataentry.html", show: true, expand: true, parent: 'biggerWidget', order: 2};
+ w.reportWidget = {title: 'report', view: "components/report/tei-report.html", show: true, expand: true, parent: 'biggerWidget', order: 3};
w.selectedWidget = {title: 'current_selections', view: "components/selected/selected.html", show: false, expand: true, parent: 'smallerWidget', order: 0};
w.profileWidget = {title: 'profile', view: "components/profile/profile.html", show: true, expand: true, parent: 'smallerWidget', order: 1};
w.relationshipWidget = {title: 'relationships', view: "components/relationship/relationship.html", show: true, expand: true, parent: 'smallerWidget', order: 2};
@@ -1061,6 +1062,55 @@
};
})
+/* factory to fetch and process programValidations */
+.factory('MetaDataFactory', function($q, $rootScope, TCStorageService) {
+
+ return {
+ get: function(store, uid){
+
+ var def = $q.defer();
+
+ TCStorageService.currentStore.open().done(function(){
+ TCStorageService.currentStore.get(store, uid).done(function(pv){
+ $rootScope.$apply(function(){
+ def.resolve(pv);
+ });
+ });
+ });
+ return def.promise;
+ },
+ getByProgram: function(store, program){
+ var def = $q.defer();
+ var obj = [];
+
+ TCStorageService.currentStore.open().done(function(){
+ TCStorageService.currentStore.getAll(store, program).done(function(pvs){
+ angular.forEach(pvs, function(pv){
+ if(pv.program.id === program){
+ obj.push(pv);
+ }
+ });
+ $rootScope.$apply(function(){
+ def.resolve(obj);
+ });
+ });
+ });
+ return def.promise;
+ },
+ getAll: function(store){
+ var def = $q.defer();
+ TCStorageService.currentStore.open().done(function(){
+ TCStorageService.currentStore.getAll(store).done(function(pvs){
+ $rootScope.$apply(function(){
+ def.resolve(pvs);
+ });
+ });
+ });
+ return def.promise;
+ }
+ };
+})
+
/* Returns a function for getting rules for a specific program */
.factory('TrackerRulesFactory', function($q,$rootScope,TCStorageService){
return{
@@ -1755,5 +1805,6 @@
}
return event;
}
- };
+ };
+
});
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js 2015-06-17 21:53:57 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/tracker-capture.js 2015-06-21 22:18:40 +0000
@@ -29,7 +29,7 @@
dhis2.tc.store = new dhis2.storage.Store({
name: 'dhis2tc',
adapters: [dhis2.storage.IndexedDBAdapter, dhis2.storage.DomSessionStorageAdapter, dhis2.storage.InMemoryAdapter],
- objectStores: ['programs', 'programStages', 'trackedEntities', 'trackedEntityForms', 'attributes', 'relationshipTypes', 'optionSets', 'programValidations', 'ouLevels', 'programRuleVariables', 'programRules']
+ objectStores: ['programs', 'programStages', 'trackedEntities', 'trackedEntityForms', 'attributes', 'relationshipTypes', 'optionSets', 'programValidations', 'programIndicators', 'ouLevels', 'programRuleVariables', 'programRules','constants']
});
(function($) {
@@ -132,6 +132,7 @@
promise = promise.then( dhis2.tc.store.open );
promise = promise.then( getUserRoles );
promise = promise.then( getCalendarSetting );
+ promise = promise.then( getConstants );
promise = promise.then( getRelationships );
promise = promise.then( getTrackedEntities );
promise = promise.then( getMetaPrograms );
@@ -146,7 +147,9 @@
promise = promise.then( getMetaProgramRules );
promise = promise.then( getProgramRules );
promise = promise.then( getMetaProgramValidations );
- promise = promise.then( getProgramValidations );
+ promise = promise.then( getProgramValidations );
+ promise = promise.then( getMetaProgramIndicators );
+ promise = promise.then( getProgramIndicators );
promise = promise.then( getTrackedEntityForms );
promise = promise.then( getOrgUnitLevels );
promise.done(function() {
@@ -206,6 +209,16 @@
return def.promise();
}
+function getConstants()
+{
+ dhis2.tc.store.getKeys( 'constants').done(function(res){
+ if(res.length > 0){
+ return;
+ }
+ return getD2Objects('constants', 'constants', '../api/constants.json', 'paging=false&fields=id,name,displayName,value');
+ });
+}
+
function getRelationships()
{
dhis2.tc.store.getKeys( 'relationshipTypes').done(function(res){
@@ -680,7 +693,7 @@
def.resolve();
promise = promise.done( function () {
- mainDef.resolve( data );
+ mainDef.resolve( data.programs );
} );
}).fail(function(){
mainDef.resolve( null );
@@ -823,6 +836,16 @@
};
}
+function getMetaProgramIndicators( programs )
+{
+ return getD2MetaObject(programs, 'programIndicators', '../api/programIndicators.json', 'paging=false&fields=id,program[id]');
+}
+
+function getProgramIndicators( programIndicators )
+{
+ return checkAndGetD2Objects( programIndicators, 'programIndicators', '../api/programIndicators', 'fields=id,name,code,shortName,expression,displayDescription,rootDate,description,valueType,DisplayName,filter,program[id]');
+}
+
function getMetaTrackeEntityAttributes( programs ){
var def = $.Deferred();
@@ -1017,4 +1040,151 @@
return def.promise();
});
+}
+
+function getD2MetaObject( programs, objNames, url, filter )
+{
+ if( !programs ){
+ return;
+ }
+
+ var def = $.Deferred();
+
+ var programIds = [];
+ _.each( _.values( programs ), function ( program ) {
+ if( program.id ) {
+ programIds.push( program.id );
+ }
+ });
+
+ $.ajax({
+ url: url,
+ type: 'GET',
+ data:filter
+ }).done( function(response) {
+ var objs = [];
+ _.each( _.values( response[objNames]), function ( o ) {
+ if( o &&
+ o.id &&
+ o.program &&
+ o.program.id &&
+ programIds.indexOf( o.program.id ) !== -1) {
+
+ objs.push( o );
+ }
+
+ });
+
+ def.resolve( {programs: programs, self: objs} );
+
+ }).fail(function(){
+ def.resolve( null );
+ });
+
+ return def.promise();
+}
+
+function checkAndGetD2Objects( obj, store, url, filter )
+{
+ if( !obj || !obj.programs || !obj.self ){
+ return;
+ }
+
+ var mainDef = $.Deferred();
+ var mainPromise = mainDef.promise();
+
+ var def = $.Deferred();
+ var promise = def.promise();
+
+ var builder = $.Deferred();
+ var build = builder.promise();
+
+ _.each( _.values( obj.self ), function ( obj) {
+ build = build.then(function() {
+ var d = $.Deferred();
+ var p = d.promise();
+ dhis2.tc.store.get(store, obj.id).done(function(o) {
+ if(!o) {
+ promise = promise.then( getD2Object( obj.id, store, url, filter, 'idb' ) );
+ }
+ d.resolve();
+ });
+
+ return p;
+ });
+ });
+
+ build.done(function() {
+ def.resolve();
+ promise = promise.done( function () {
+ mainDef.resolve( obj.programs );
+ } );
+ }).fail(function(){
+ mainDef.resolve( null );
+ });
+
+ builder.resolve();
+
+ return mainPromise;
+}
+
+function getD2Objects(store, objs, url, filter)
+{
+ var def = $.Deferred();
+
+ $.ajax({
+ url: url,
+ type: 'GET',
+ data: filter
+ }).done(function(response) {
+ if(response[objs]){
+ dhis2.tc.store.setAll( store, response[objs] );
+ }
+ def.resolve();
+ }).fail(function(){
+ def.resolve();
+ });
+
+ return def.promise();
+}
+
+
+function getD2Object( id, store, url, filter, storage )
+{
+ return function() {
+ if(id){
+ url = url + '/' + id + '.json';
+ }
+ return $.ajax( {
+ url: url,
+ type: 'GET',
+ data: filter
+ }).done( function( response ){
+ if(storage === 'idb'){
+ if( response && response.id) {
+ dhis2.tc.store.set( store, response );
+ }
+ }
+ if(storage === 'localStorage'){
+ localStorage[store] = JSON.stringify(response);
+ }
+ if(storage === 'sessionStorage'){
+ var SessionStorageService = angular.element('body').injector().get('SessionStorageService');
+ SessionStorageService.set(store, response);
+ }
+ });
+ };
+}
+
+function uploadLocalData()
+{
+ var OfflineECStorageService = angular.element('body').injector().get('OfflineECStorageService');
+ setHeaderWaitMessage(i18n_uploading_data_notification);
+
+ OfflineECStorageService.uploadLocalData().then(function(){
+ dhis2.tc.store.removeAll( 'events' );
+ log( 'Successfully uploaded local events' );
+ setHeaderDelayMessage( i18n_sync_success );
+ selection.responseReceived(); //notify angular
+ });
}
\ No newline at end of file
=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.services.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.services.js 2015-06-19 06:01:29 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/dhis2/dhis2.angular.services.js 2015-06-21 22:18:40 +0000
@@ -710,13 +710,13 @@
})
/* service for building variables based on the data in users fields */
-.service('VariableService', function($rootScope,$q,TrackerRuleVariableFactory,$filter,orderByFilter,$log){
+.service('VariableService', function($rootScope,$q,TrackerRuleVariableFactory,DateUtils,CalendarService,MetaDataFactory,$filter,orderByFilter,$log){
return {
- getVariables: function(programid, executingEvent, allEventsByStage, allDataElements, selectedEntity) {
+ getVariables: function(programid, executingEvent, allEventsByStage, allDataElements, selectedEntity, variablesFromIndicators, selectedEnrollment) {
var thePromisedVariables = $q.defer();
var variables = {};
- var pushVariable = function(variablename, variableValue, variableType, variablefound) {
+ var pushVariable = function(variablename, variableValue, variableType, variablefound, variablePrefix) {
//First clean away single or double quotation marks at the start and end of the variable name.
variableValue = $filter('trimquotes')(variableValue);
@@ -745,138 +745,161 @@
variables[variablename] = {
variableValue:variableValue,
variableType:variableType,
- hasValue:variablefound
+ hasValue:variablefound,
+ variablePrefix:variablePrefix
};
};
-
- TrackerRuleVariableFactory.getProgramRuleVariables(programid).then(function(programVariables){
-
- var allEventsSorted = [];
- var currentEvent = executingEvent;
- var eventsSortedPerProgramStage = [];
-
- for(var key in allEventsByStage){
- if(allEventsByStage.hasOwnProperty(key)){
- eventsSortedPerProgramStage[key] = [];
- angular.forEach(allEventsByStage[key], function(event){
- allEventsSorted.push(event);
- eventsSortedPerProgramStage[key].push(event);
- });
- eventsSortedPerProgramStage[key] = orderByFilter(eventsSortedPerProgramStage[key], '-sortingDate').reverse();
+ MetaDataFactory.getAll('constants').then(function(constants) {
+ TrackerRuleVariableFactory.getProgramRuleVariables(programid).then(function(programVariables){
+
+ programVariables = programVariables.concat(variablesFromIndicators);
+
+ var allEventsSorted = [];
+ var currentEvent = executingEvent;
+ var eventsSortedPerProgramStage = [];
+
+ for(var key in allEventsByStage){
+ if(allEventsByStage.hasOwnProperty(key)){
+ eventsSortedPerProgramStage[key] = [];
+ angular.forEach(allEventsByStage[key], function(event){
+ allEventsSorted.push(event);
+ eventsSortedPerProgramStage[key].push(event);
+ });
+ eventsSortedPerProgramStage[key] = orderByFilter(eventsSortedPerProgramStage[key], '-sortingDate').reverse();
+ }
}
- }
- allEventsSorted = orderByFilter(allEventsSorted, '-sortingDate').reverse();
-
- var allDes = allDataElements;
-
- angular.forEach(programVariables, function(programVariable) {
- var valueFound = false;
- if(programVariable.programRuleVariableSourceType === "DATAELEMENT_NEWEST_EVENT_PROGRAM_STAGE"){
- if(programVariable.programStage) {
- angular.forEach(eventsSortedPerProgramStage[programVariable.programStage.id], function(event) {
- if(angular.isDefined(event[programVariable.dataElement.id])
- && event[programVariable.dataElement.id] !== null ){
+ allEventsSorted = orderByFilter(allEventsSorted, '-sortingDate').reverse();
+
+ var allDes = allDataElements;
+
+ angular.forEach(programVariables, function(programVariable) {
+ var dataElementId = programVariable.dataElement;
+ if(programVariable.dataElement.id) {
+ dataElementId = programVariable.dataElement.id;
+ }
+
+ var programStageId = programVariable.programStage;
+ if(programVariable.programStage.id) {
+ programStageId = programVariable.programStage.id;
+ }
+
+ var valueFound = false;
+ if(programVariable.programRuleVariableSourceType === "DATAELEMENT_NEWEST_EVENT_PROGRAM_STAGE"){
+ if(programVariable.programStage) {
+ angular.forEach(eventsSortedPerProgramStage[programStageId], function(event) {
+ if(angular.isDefined(event[dataElementId])
+ && event[dataElementId] !== null ){
+ valueFound = true;
+ pushVariable(programVariable.name, event[dataElementId], allDes[dataElementId].dataElement.type, valueFound, '#');
+ }
+ });
+ } else {
+ $log.warn("Variable id:'" + programVariable.id + "' name:'" + programVariable.name
+ + "' does not have a programstage defined,"
+ + " despite that the variable has sourcetype DATAELEMENT_NEWEST_EVENT_PROGRAM_STAGE" );
+ }
+
+ }
+ else if(programVariable.programRuleVariableSourceType === "DATAELEMENT_NEWEST_EVENT_PROGRAM"){
+ angular.forEach(allEventsSorted, function(event) {
+ if(angular.isDefined(event[dataElementId])
+ && event[dataElementId] !== null ){
valueFound = true;
- pushVariable(programVariable.name, event[programVariable.dataElement.id], allDes[programVariable.dataElement.id].dataElement.type, valueFound );
- }
+ pushVariable(programVariable.name, event[dataElementId], allDes[dataElementId].dataElement.type, valueFound, '#' );
+ }
});
- } else {
- $log.warn("Variable id:'" + programVariable.id + "' name:'" + programVariable.name
- + "' does not have a programstage defined,"
- + " despite that the variable has sourcetype DATAELEMENT_NEWEST_EVENT_PROGRAM_STAGE" );
}
-
- }
- else if(programVariable.programRuleVariableSourceType === "DATAELEMENT_NEWEST_EVENT_PROGRAM"){
- angular.forEach(allEventsSorted, function(event) {
- if(angular.isDefined(event[programVariable.dataElement.id])
- && event[programVariable.dataElement.id] !== null ){
+ else if(programVariable.programRuleVariableSourceType === "DATAELEMENT_CURRENT_EVENT"){
+ if(angular.isDefined(currentEvent[dataElementId])
+ && currentEvent[dataElementId] !== null ){
valueFound = true;
- pushVariable(programVariable.name, event[programVariable.dataElement.id], allDes[programVariable.dataElement.id].dataElement.type, valueFound );
- }
- });
- }
- else if(programVariable.programRuleVariableSourceType === "DATAELEMENT_CURRENT_EVENT"){
- if(angular.isDefined(currentEvent[programVariable.dataElement.id])
- && currentEvent[programVariable.dataElement.id] !== null ){
+ pushVariable(programVariable.name, currentEvent[dataElementId], allDes[dataElementId].dataElement.type, valueFound, '#' );
+ }
+ }
+ else if(programVariable.programRuleVariableSourceType === "DATAELEMENT_PREVIOUS_EVENT"){
+ //Only continue checking for a value if there is more than one event.
+ if(allEventsSorted && allEventsSorted.length > 1) {
+ var previousvalue = null;
+ var currentEventPassed = false;
+ for(var i = 0; i < allEventsSorted.length; i++) {
+ //Store the values as we iterate through the stages
+ //If the event[i] is not the current event, it is older(previous). Store the previous value if it exists
+ if(!currentEventPassed && allEventsSorted[i] !== currentEvent &&
+ angular.isDefined(allEventsSorted[i][dataElementId])) {
+ previousvalue = allEventsSorted[i][dataElementId];
+ valueFound = true;
+ }
+ else if(allEventsSorted[i] === currentEvent) {
+ //We have iterated to the newest event - store the last collected variable value - if any is found:
+ if(valueFound) {
+ pushVariable(programVariable.name, previousvalue, allDes[dataElementId].dataElement.type, valueFound, '#' );
+ }
+ //Set currentEventPassed, ending the iteration:
+ currentEventPassed = true;
+ }
+ }
+ }
+ }
+ else if(programVariable.programRuleVariableSourceType === "TEI_ATTRIBUTE"){
+ angular.forEach(selectedEntity.attributes , function(attribute) {
+ if(!valueFound) {
+ if(attribute.attribute === programVariable.trackedEntityAttribute.id) {
+ valueFound = true;
+ pushVariable(programVariable.name, attribute.value, attribute.type, valueFound, '#' );
+ }
+ }
+ });
+ }
+ else if(programVariable.programRuleVariableSourceType === "CALCULATED_VALUE"){
+ //We won't assign the calculated variables at this step. The rules execution will calculate and assign the variable.
+ }
+ else if(programVariable.programRuleVariableSourceType === "NUMBEROFEVENTS_PROGRAMSTAGE"){
+ var numberOfEvents = 0;
+ if( programVariable.programStage && eventsSortedPerProgramStage[programStageId] ) {
+ numberOfEvents = eventsSortedPerProgramStage[programStageId].length;
+ }
valueFound = true;
- pushVariable(programVariable.name, currentEvent[programVariable.dataElement.id], allDes[programVariable.dataElement.id].dataElement.type, valueFound );
- }
- }
- else if(programVariable.programRuleVariableSourceType === "DATAELEMENT_PREVIOUS_EVENT"){
- //Only continue checking for a value if there is more than one event.
- if(allEventsSorted && allEventsSorted.length > 1) {
- var previousvalue = null;
- var currentEventPassed = false;
- for(var i = 0; i < allEventsSorted.length; i++) {
- //Store the values as we iterate through the stages
- //If the event[i] is not the current event, it is older(previous). Store the previous value if it exists
- if(!currentEventPassed && allEventsSorted[i] !== currentEvent &&
- angular.isDefined(allEventsSorted[i][programVariable.dataElement.id])) {
- previousvalue = allEventsSorted[i][programVariable.dataElement.id];
- valueFound = true;
- }
- else if(allEventsSorted[i] === currentEvent) {
- //We have iterated to the newest event - store the last collected variable value - if any is found:
- if(valueFound) {
- pushVariable(programVariable.name, previousvalue, allDes[programVariable.dataElement.id].dataElement.type, valueFound );
- }
- //Set currentEventPassed, ending the iteration:
- currentEventPassed = true;
- }
- }
- }
- }
- else if(programVariable.programRuleVariableSourceType === "TEI_ATTRIBUTE"){
- angular.forEach(selectedEntity.attributes , function(attribute) {
- if(!valueFound) {
- if(attribute.attribute === programVariable.trackedEntityAttribute.id) {
- valueFound = true;
- pushVariable(programVariable.name, attribute.value, attribute.type, valueFound );
- }
- }
- });
- }
- else if(programVariable.programRuleVariableSourceType === "CALCULATED_VALUE"){
- //We won't assign the calculated variables at this step. The rules execution will calculate and assign the variable.
- }
- else if(programVariable.programRuleVariableSourceType === "NUMBEROFEVENTS_PROGRAMSTAGE"){
- var numberOfEvents = 0;
- if( programVariable.programStage && eventsSortedPerProgramStage[programVariable.programStage.id] ) {
- numberOfEvents = eventsSortedPerProgramStage[programVariable.programStage.id].length;
- }
- valueFound = true;
- pushVariable(programVariable.name, numberOfEvents, 'int', valueFound );
- }
- else {
- //Missing handing of ruletype
- $log.warn("Unknown programRuleVariableSourceType:" + programVariable.programRuleVariableSourceType);
- }
-
-
- if(!valueFound){
- //If there is still no value found, assign default value:
- if(programVariable.dataElement) {
- var dataElement = allDes[programVariable.dataElement.id];
- if( dataElement ) {
- pushVariable(programVariable.name, "", dataElement.dataElement.type );
- }
+ pushVariable(programVariable.name, numberOfEvents, 'int', valueFound, '#' );
+ }
+ else {
+ //Missing handing of ruletype
+ $log.warn("Unknown programRuleVariableSourceType:" + programVariable.programRuleVariableSourceType);
+ }
+
+
+ if(!valueFound){
+ //If there is still no value found, assign default value:
+ if(programVariable.dataElement) {
+ var dataElement = allDes[dhis2.tc];
+ if( dataElement ) {
+ pushVariable(programVariable.name, "", dataElement.dataElement.type, false, '#' );
+ }
+ else {
+ $log.warn("Variable #{" + programVariable.name + "} is linked to a dataelement that is not part of the program");
+ pushVariable(programVariable.name, "", "string",false, '#' );
+ }
+ }
else {
- $log.warn("Variable #{" + programVariable.name + "} is linked to a dataelement that is not part of the program");
- pushVariable(programVariable.name, "", "string" );
+ pushVariable(programVariable.name, "", "string",false, '#' );
}
}
- else {
- pushVariable(programVariable.name, "", "string" );
- }
- }
- });
-
- //add context variables:
- //last parameter "valuefound" is always true for event date
- pushVariable('eventdate', executingEvent.eventDate, 'date', true );
-
- thePromisedVariables.resolve(variables);
+ });
+
+ //add context variables:
+ //last parameter "valuefound" is always true for event date
+ pushVariable('incident_date', executingEvent.eventDate, 'date', true, 'V' );
+ pushVariable('enrollment_date', selectedEnrollment.dateOfEnrollment, 'date', true, 'V' );
+ pushVariable('current_date', DateUtils.getToday(), 'date', true, 'V' );
+ //pushVariable('value_count', executingEvent.eventDate, 'date', true, 'V' );
+ //pushVariable('zero_pos_value_count', executingEvent.eventDate, 'date', true, 'V' );
+
+ //Push all constant values:
+ angular.forEach(constants, function(constant){
+ pushVariable(constant.id, constant.value, 'int', true, 'C' );
+ });
+
+ thePromisedVariables.resolve(variables);
+ });
});
return thePromisedVariables.promise;
@@ -885,28 +908,29 @@
})
/* service for executing tracker rules and broadcasting results */
-.service('TrackerRulesExecutionService', function(TrackerRulesFactory,VariableService, $rootScope, $log, $filter, orderByFilter){
+.service('TrackerRulesExecutionService', function(TrackerRulesFactory, MetaDataFactory, VariableService, $rootScope, $log, $q, $filter, orderByFilter){
return {
- executeRules: function(programid, executingEvent, allEventsByStage, allDataElements, selectedEntity) {
+ executeRules: function(programid, executingEvent, allEventsByStage, allDataElements, selectedEntity, selectedEnrollment ) {
//When debugging rules, the caller should provide a variable for wether or not the rules is being debugged.
//hard coding this for now:
var debug = true;
var verbose = true;
var variablesHash = {};
-
+
var replaceVariables = function(expression) {
//replaces the variables in an expression with actual variable values.
//First check if the expression contains variables at all(any dollar signs):
- if(expression.indexOf('#') !== -1) {
+ if(expression.indexOf('#{') !== -1) {
//Find every variable name in the expression;
- var variablespresent = expression.match(/#{\w+}/g);
+ var variablespresent = expression.match(/#{\w+.?\w*}/g);
//Replace each matched variable:
angular.forEach(variablespresent, function(variablepresent) {
- //First strip away any dollar signs from the variable name:
+ //First strip away any prefix and postfix signs from the variable name:
variablepresent = variablepresent.replace("#{","").replace("}","");
- if(angular.isDefined(variablesHash[variablepresent])) {
+ if(angular.isDefined(variablesHash[variablepresent]) &&
+ variablesHash[variablepresent].variablePrefix === '#') {
//Replace all occurrences of the variable name(hence using regex replacement):
expression = expression.replace(new RegExp("#{" + variablepresent + "}", 'g'),
variablesHash[variablepresent].variableValue);
@@ -914,8 +938,49 @@
else {
$log.warn("Expression " + expression + " conains variable " + variablepresent
+ " - but this variable is not defined." );
- }
-
+ }
+ });
+ }
+
+ if(expression.indexOf('V{') !== -1) {
+ //Find every variable name in the expression;
+ var variablespresent = expression.match(/V{\w+.?\w*}/g);
+ //Replace each matched variable:
+ angular.forEach(variablespresent, function(variablepresent) {
+ //First strip away any prefix and postfix signs from the variable name:
+ variablepresent = variablepresent.replace("V{","").replace("}","");
+
+ if(angular.isDefined(variablesHash[variablepresent]) &&
+ variablesHash[variablepresent].variablePrefix === 'V') {
+ //Replace all occurrences of the variable name(hence using regex replacement):
+ expression = expression.replace(new RegExp("V{" + variablepresent + "}", 'g'),
+ variablesHash[variablepresent].variableValue);
+ }
+ else {
+ $log.warn("Expression " + expression + " conains context variable " + variablepresent
+ + " - but this variable is not defined." );
+ }
+ });
+ }
+
+ if(expression.indexOf('C{') !== -1) {
+ //Find every constant in the expression;
+ var variablespresent = expression.match(/C{\w+.?\w*}/g);
+ //Replace each matched variable:
+ angular.forEach(variablespresent, function(variablepresent) {
+ //First strip away any prefix and postfix signs from the variable name:
+ variablepresent = variablepresent.replace("C{","").replace("}","");
+
+ if(angular.isDefined(variablesHash[variablepresent]) &&
+ variablesHash[variablepresent].variablePrefix === 'C') {
+ //Replace all occurrences of the variable name(hence using regex replacement):
+ expression = expression.replace(new RegExp("C{" + variablepresent + "}", 'g'),
+ variablesHash[variablepresent].variableValue);
+ }
+ else {
+ $log.warn("Expression " + expression + " conains constant " + variablepresent
+ + " - but this constant is not defined." );
+ }
});
}
return expression;
@@ -1034,119 +1099,196 @@
return answer;
};
-
- VariableService.getVariables(programid, executingEvent, allEventsByStage, allDataElements, selectedEntity).then(function(variablesReceived){
- TrackerRulesFactory.getProgramStageRules(programid, executingEvent.programStage).then(function(rules){
- //But run rules in priority - lowest number first(priority null is last)
- rules = orderByFilter(rules, 'priority');
-
- variablesHash = variablesReceived;
-
- if(angular.isObject(rules) && angular.isArray(rules)){
- //The program has rules, and we want to run them.
- //Prepare repository unless it is already prepared:
- if(angular.isUndefined( $rootScope.ruleeffects ) ) {
- $rootScope.ruleeffects = {};
- }
-
- if(angular.isUndefined( $rootScope.ruleeffects[executingEvent.event] )){
- $rootScope.ruleeffects[executingEvent.event] = {};
- }
-
- var updatedEffectsExits = false;
-
- angular.forEach(rules, function(rule) {
- var ruleEffective = false;
-
- var expression = rule.condition;
- //Go through and populate variables with actual values, but only if there actually is any replacements to be made(one or more "$" is present)
- if(expression) {
- if(expression.indexOf('#') !== -1) {
- expression = replaceVariables(expression);
- }
- //run expression:
- ruleEffective = runExpression(expression, rule.condition, "rule:" + rule.id);
- } else {
- $log.warn("Rule id:'" + rule.id + "'' and name:'" + rule.name + "' had no condition specified. Please check rule configuration.");
- }
-
- angular.forEach(rule.programRuleActions, function(action){
- //In case the effect-hash is not populated, add entries
- if(angular.isUndefined( $rootScope.ruleeffects[executingEvent.event][action.id] )){
- $rootScope.ruleeffects[executingEvent.event][action.id] = {
- id:action.id,
- location:action.location,
- action:action.programRuleActionType,
- dataElement:action.dataElement,
- content:action.content,
- data:action.data,
- ineffect:undefined
- };
- }
-
- //In case the rule is effective and contains specific data,
- //the effect be refreshed from the variables list.
- //If the rule is not effective we can skip this step
- if(ruleEffective && action.data)
- {
- //The key data might be containing a dollar sign denoting that the key data is a variable.
- //To make a lookup in variables hash, we must make a lookup without the dollar sign in the variable name
- //The first strategy is to make a direct lookup. In case the "data" expression is more complex, we have to do more replacement and evaluation.
-
- var nameWithoutBrackets = action.data.replace('#{','').replace('}','');
- if(angular.isDefined(variablesHash[nameWithoutBrackets]))
- {
- //The variable exists, and is replaced with its corresponding value
- $rootScope.ruleeffects[executingEvent.event][action.id].data =
- variablesHash[nameWithoutBrackets].variableValue;
- }
- else if(action.data.indexOf('#') !== -1)
- {
- //Since the value couldnt be looked up directly, and contains a dollar sign, the expression was more complex
- //Now we will have to make a thorough replacement and separate evaluation to find the correct value:
- $rootScope.ruleeffects[executingEvent.event][action.id].data = replaceVariables(action.data);
- //In a scenario where the data contains a complex expression, evaluate the expression to compile(calculate) the result:
- $rootScope.ruleeffects[executingEvent.event][action.id].data = runExpression($rootScope.ruleeffects[executingEvent.event][action.id].data, action.data, "action:" + action.id);
- }
- }
-
- //Update the rule effectiveness if it changed in this evaluation;
- if($rootScope.ruleeffects[executingEvent.event][action.id].ineffect !== ruleEffective)
- {
- //There is a change in the rule outcome, we need to update the effect object.
- updatedEffectsExits = true;
- $rootScope.ruleeffects[executingEvent.event][action.id].ineffect = ruleEffective;
- }
-
- //In case the rule is of type "assign variable" and the rule is effective,
- //the variable data result needs to be applied to the correct variable:
- if($rootScope.ruleeffects[executingEvent.event][action.id].action === "ASSIGNVARIABLE" && $rootScope.ruleeffects[executingEvent.event][action.id].ineffect){
- //from earlier evaluation, the data portion of the ruleeffect now contains the value of the variable to be assign.
- //the content portion of the ruleeffect defines the name for the variable, when dollar is removed:
- var variabletoassign = $rootScope.ruleeffects[executingEvent.event][action.id].content.replace("#{","").replace("}","");
-
- if(!angular.isDefined(variablesHash[variabletoassign])){
- $log.warn("Variable " + variabletoassign + " was not defined.");
- }
-
- //Even if the variable is not defined: we assign it:
- if(variablesHash[variabletoassign].variableValue !== $rootScope.ruleeffects[executingEvent.event][action.id].data){
- //If the variable was actually updated, we assume that there is an updated ruleeffect somewhere:
+ var getIndicatorRules = function (programid) {
+ var def = $q.defer();
+ MetaDataFactory.getByProgram('programIndicators', programid).then(function(pis){
+ var variables = [];
+
+ var programRules = [];
+
+ angular.forEach(pis, function(pi){
+ var newAction = {
+ id:pi.id,
+ content:pi.displayDescription,
+ data:pi.expression,
+ programRuleActionType:'DISPLAYKEYVALUEPAIR',
+ location:'indicators'
+ };
+ var newRule = {
+ name:pi.name,
+ shortname:pi.shortname,
+ code:pi.code,
+ program:pi.program,
+ description:pi.description,
+ condition:pi.filter ? pi.filter : 'true',
+ programRuleActions: [newAction]
+ };
+
+ programRules.push(newRule);
+
+ var variablesInCondition = newRule.condition.match(/#{\w+.?\w*}/g);
+ var variablesInData = newAction.data.match(/#{\w+.?\w*}/g);
+
+ var pushDirectAddressedVariable = function(variableWithCurls) {
+ var variableName = variableWithCurls.replace("#{","").replace("}","");
+ var variableNameParts = variableName.split('.');
+
+
+ if(variableNameParts.length === 2) {
+ //this is a programstage and dataelement specification. translate to program variable:
+ variables.push({
+ name:variableName,
+ programRuleVariableSourceType:'DATAELEMENT_NEWEST_EVENT_PROGRAM_STAGE',
+ dataElement:variableNameParts[1],
+ programStage:variableNameParts[0],
+ program:programid
+ });
+ }
+ else if(variableNameParts.length === 1)
+ {
+ //This is an attribute - let us translate to program variable:
+ variables.push({
+ name:variableName,
+ programRuleVariableSourceType:'TEI_ATTRIBUTE',
+ trackedEntityAttribute:variableNameParts[0],
+ program:programid
+ });
+ }
+
+ };
+
+ angular.forEach(variablesInCondition, function(variableInCondition) {
+ pushDirectAddressedVariable(variableInCondition);
+ });
+
+ angular.forEach(variablesInData, function(variableInData) {
+ pushDirectAddressedVariable(variableInData);
+ });
+ });
+
+ def.resolve({rules:programRules,variables:variables});
+ });
+ return def.promise;
+ };
+
+
+ getIndicatorRules(programid).then(function(indicatorRulesAndVariables){
+ VariableService.getVariables(programid, executingEvent, allEventsByStage, allDataElements, selectedEntity,indicatorRulesAndVariables.variables, selectedEnrollment).then(function(variablesReceived){
+ TrackerRulesFactory.getProgramStageRules(programid, executingEvent.programStage).then(function(rules){
+ //Concatenate rules produced by indicator definitions into the other rules:
+ rules = rules.concat(indicatorRulesAndVariables.rules);
+
+ //Run rules in priority - lowest number first(priority null is last)
+ rules = orderByFilter(rules, 'priority');
+
+ variablesHash = variablesReceived;
+
+ if(angular.isObject(rules) && angular.isArray(rules)){
+ //The program has rules, and we want to run them.
+ //Prepare repository unless it is already prepared:
+ if(angular.isUndefined( $rootScope.ruleeffects ) ) {
+ $rootScope.ruleeffects = {};
+ }
+
+ if(angular.isUndefined( $rootScope.ruleeffects[executingEvent.event] )){
+ $rootScope.ruleeffects[executingEvent.event] = {};
+ }
+
+ var updatedEffectsExits = false;
+
+ angular.forEach(rules, function(rule) {
+ var ruleEffective = false;
+
+ var expression = rule.condition;
+ //Go through and populate variables with actual values, but only if there actually is any replacements to be made(one or more "$" is present)
+ if(expression) {
+ if(expression.indexOf('{') !== -1) {
+ expression = replaceVariables(expression);
+ }
+ //run expression:
+ ruleEffective = runExpression(expression, rule.condition, "rule:" + rule.id);
+ } else {
+ $log.warn("Rule id:'" + rule.id + "'' and name:'" + rule.name + "' had no condition specified. Please check rule configuration.");
+ }
+
+ angular.forEach(rule.programRuleActions, function(action){
+ //In case the effect-hash is not populated, add entries
+ if(angular.isUndefined( $rootScope.ruleeffects[executingEvent.event][action.id] )){
+ $rootScope.ruleeffects[executingEvent.event][action.id] = {
+ id:action.id,
+ location:action.location,
+ action:action.programRuleActionType,
+ dataElement:action.dataElement,
+ content:action.content,
+ data:action.data,
+ ineffect:undefined
+ };
+ }
+
+ //In case the rule is effective and contains specific data,
+ //the effect be refreshed from the variables list.
+ //If the rule is not effective we can skip this step
+ if(ruleEffective && action.data)
+ {
+ //The key data might be containing a dollar sign denoting that the key data is a variable.
+ //To make a lookup in variables hash, we must make a lookup without the dollar sign in the variable name
+ //The first strategy is to make a direct lookup. In case the "data" expression is more complex, we have to do more replacement and evaluation.
+
+ var nameWithoutBrackets = action.data.replace('#{','').replace('}','');
+ if(angular.isDefined(variablesHash[nameWithoutBrackets]))
+ {
+ //The variable exists, and is replaced with its corresponding value
+ $rootScope.ruleeffects[executingEvent.event][action.id].data =
+ variablesHash[nameWithoutBrackets].variableValue;
+ }
+ else if(action.data.indexOf('{') !== -1)
+ {
+ //Since the value couldnt be looked up directly, and contains a dollar sign, the expression was more complex
+ //Now we will have to make a thorough replacement and separate evaluation to find the correct value:
+ $rootScope.ruleeffects[executingEvent.event][action.id].data = replaceVariables(action.data);
+ //In a scenario where the data contains a complex expression, evaluate the expression to compile(calculate) the result:
+ $rootScope.ruleeffects[executingEvent.event][action.id].data = runExpression($rootScope.ruleeffects[executingEvent.event][action.id].data, action.data, "action:" + action.id);
+ }
+ }
+
+ //Update the rule effectiveness if it changed in this evaluation;
+ if($rootScope.ruleeffects[executingEvent.event][action.id].ineffect !== ruleEffective)
+ {
+ //There is a change in the rule outcome, we need to update the effect object.
updatedEffectsExits = true;
- //Then we assign the new value:
- variablesHash[variabletoassign].variableValue = $rootScope.ruleeffects[executingEvent.event][action.id].data;
- }
- }
+ $rootScope.ruleeffects[executingEvent.event][action.id].ineffect = ruleEffective;
+ }
+
+ //In case the rule is of type "assign variable" and the rule is effective,
+ //the variable data result needs to be applied to the correct variable:
+ if($rootScope.ruleeffects[executingEvent.event][action.id].action === "ASSIGNVARIABLE" && $rootScope.ruleeffects[executingEvent.event][action.id].ineffect){
+ //from earlier evaluation, the data portion of the ruleeffect now contains the value of the variable to be assign.
+ //the content portion of the ruleeffect defines the name for the variable, when dollar is removed:
+ var variabletoassign = $rootScope.ruleeffects[executingEvent.event][action.id].content.replace("#{","").replace("}","");
+
+ if(!angular.isDefined(variablesHash[variabletoassign])){
+ $log.warn("Variable " + variabletoassign + " was not defined.");
+ }
+
+ //Even if the variable is not defined: we assign it:
+ if(variablesHash[variabletoassign].variableValue !== $rootScope.ruleeffects[executingEvent.event][action.id].data){
+ //If the variable was actually updated, we assume that there is an updated ruleeffect somewhere:
+ updatedEffectsExits = true;
+ //Then we assign the new value:
+ variablesHash[variabletoassign].variableValue = $rootScope.ruleeffects[executingEvent.event][action.id].data;
+ }
+ }
+ });
});
- });
- //Broadcast rules finished if there was any actual changes to the event.
- if(updatedEffectsExits){
- $rootScope.$broadcast("ruleeffectsupdated", { event: executingEvent.event });
+ //Broadcast rules finished if there was any actual changes to the event.
+ if(updatedEffectsExits){
+ $rootScope.$broadcast("ruleeffectsupdated", { event: executingEvent.event });
+ }
}
- }
- return true;
+ return true;
+ });
});
});
}