← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 19393: Better separation of concerns when triggering tracker capture rules + some cleanup

 

------------------------------------------------------------
revno: 19393
committer: Markus Bekken <markus.bekken@xxxxxxxxx>
branch nick: dhis2
timestamp: Sun 2015-06-14 15:07:10 +0200
message:
  Better separation of concerns when triggering tracker capture rules + some cleanup
modified:
  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/rulebound/rulebound-controller.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/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-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-10 13:45:11 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/dataentry/dataentry-controller.js	2015-06-14 13:07:10 +0000
@@ -57,36 +57,73 @@
     
     //listen for rule effect changes
     $scope.$on('ruleeffectsupdated', function(event, args) {
-        angular.forEach($rootScope.ruleeffects, function(effect) {
-            if( effect.dataElement ) {
-                //in the data entry controller we only care about the "hidefield" actions
-                if(effect.action === "HIDEFIELD") {
-                    if(effect.dataElement) {
-                        //Hide the field if the hiding is in effect, and there is no data value in the field.
-                        var hide = effect.ineffect && !$scope.currentEvent[effect.dataElement.id];
-                        $scope.hiddenFields[effect.dataElement.id] = hide;
+        if($rootScope.ruleeffects[args.event]) {
+            //Establish which event was affected:
+            var affectedEvent = $scope.currentEvent;
+            //In most cases the updated effects apply to the current event. In case the affected event is not the current event, fetch the correct event to affect:
+            if(args.event !== affectedEvent.event) {
+                angular.forEach($scope.currentStageEvents, function(searchedEvent) {
+                    if(searchedEvent.event === args.event) {
+                        affectedEvent = searchedEvent;
                     }
-                    else {
-                        $log.warn("ProgramRuleAction " + effect.id + " is of type HIDEFIELD, bot does not have a dataelement defined");
+                });
+            }
+            
+            angular.forEach($rootScope.ruleeffects[args.event], function(effect) {
+                if( effect.dataElement ) {
+                    //in the data entry controller we only care about the "hidefield" actions
+                    if(effect.action === "HIDEFIELD") {
+                        if(effect.dataElement) {
+                            if(effect.ineffect && affectedEvent[effect.dataElement.id]) {
+                                //If a field is going to be hidden, but contains a value, we need to take action;
+                                if(effect.content) {
+                                    //TODO: Alerts is going to be replaced with a proper display mecanism.
+                                    alert(effect.content);
+                                }
+                                else {
+                                    //TODO: Alerts is going to be replaced with a proper display mecanism.
+                                    alert($scope.prStDes[effect.dataElement.id].dataElement.formName + "Was blanked out and hidden by your last action");
+                                }
+
+                                //Blank out the value:
+                                affectedEvent[effect.dataElement.id] = "";
+                                $scope.saveDatavalueForEvent($scope.prStDes[effect.dataElement.id],null,affectedEvent);
+                            }
+
+                            $scope.hiddenFields[effect.dataElement.id] = effect.ineffect;
+                        }
+                        else {
+                            $log.warn("ProgramRuleAction " + effect.id + " is of type HIDEFIELD, bot does not have a dataelement defined");
+                        }
                     }
                 }
-            }
-        });
+            });
+        }
     });
+    
     //check if field is hidden
     $scope.isHidden = function(id) {
         //In case the field contains a value, we cant hide it. 
         //If we hid a field with a value, it would falsely seem the user was aware that the value was entered in the UI.
-        if($scope.currentEvent[id])
-        {
+        if($scope.currentEvent[id]) {
            return false; 
         }
-        else
-        {
+        else {
             return $scope.hiddenFields[id];
         }
     }; 
     
+    $scope.executeRules = function() {
+        //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);
+           });
+        } else {
+           TrackerRulesExecutionService.executeRules($scope.selectedProgramId,$scope.currentEvent,$scope.eventsByStage,$scope.prStDes,$scope.selectedTei);
+        }
+    };
+    
     
     //listen for the selected items
     $scope.$on('dashboardWidgets', function() {
@@ -357,7 +394,7 @@
 
         //Execute rules for the first time, to make the initial page appear correctly.
         //Subsequent calls will be made from the "saveDataValue" function.
-        TrackerRulesExecutionService.executeRules($scope);
+        $scope.executeRules();
     };
     
     function updateCurrentEventInStage(){
@@ -378,7 +415,7 @@
         $scope.saveDatavalueForEvent(prStDe,field,$scope.currentEvent);
     };
 
-    $scope.saveDatavalueForEvent = function(prStDe,field,eventToSave,object){
+    $scope.saveDatavalueForEvent = function(prStDe,field,eventToSave){
         //Blank out the input-saved class on the last saved due date:
         $scope.eventDateSaved = false;
         
@@ -444,7 +481,8 @@
                 
                 $scope.currentStageEventsOriginal = angular.copy($scope.currentStageEvents);
 
-				TrackerRulesExecutionService.executeRules($scope);
+                //Run rules on updated data:
+		$scope.executeRules();
             });
             
         }

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/rulebound/rulebound-controller.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/rulebound/rulebound-controller.js	2015-06-02 05:55:14 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/components/rulebound/rulebound-controller.js	2015-06-14 13:07:10 +0000
@@ -20,11 +20,11 @@
         var keyDataInEffect = false;
         
         //Bind non-bound rule effects, if any.
-        angular.forEach($rootScope.ruleeffects, function(effect) {
-            if(effect.location == $scope.widgetCode){
+        angular.forEach($rootScope.ruleeffects[args.event], function(effect) {
+            if(effect.location === $scope.widgetCode){
                 //This effect is affecting the local widget
                 
-                if(effect.action == "DISPLAYTEXT") {
+                if(effect.action === "DISPLAYTEXT") {
                     //this action is display text. Make sure the displaytext is
                     //added to the local list of displayed texts
                     if(!angular.isObject($scope.displayTextEffects[effect.id])){
@@ -35,7 +35,7 @@
                         textInEffect = true;
                     }
                 }
-                else if(effect.action == "DISPLAYKEYVALUEPAIR") {
+                else if(effect.action === "DISPLAYKEYVALUEPAIR") {
                     //this action is display text. Make sure the displaytext is
                     //added to the local list of displayed texts
                     if(!angular.isObject($scope.displayTextEffects[effect.id])){
@@ -46,7 +46,7 @@
                         keyDataInEffect = true;
                     }
                 } else {
-                    $log.warn("action: '" + effect.action + "' not supported by rulebound-controller.js")
+                    $log.warn("action: '" + effect.action + "' not supported by rulebound-controller.js");
                 }
             }
         });

=== 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-10 13:45:11 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-tracker-capture/scripts/services.js	2015-06-14 13:07:10 +0000
@@ -1778,66 +1778,66 @@
 /* service for building variables based on the data in users fields */
 .service('VariableService', function($rootScope,$q,TrackerRuleVariableFactory,$filter,orderByFilter,$log){
     return {
-        getVariables: function($scope) {
+        getVariables: function(programid, executingEvent, allEventsByStage, allDataElements, selectedEntity) {
             var thePromisedVariables = $q.defer();
-            var variables = [];
+            var variables = {};
             
-            $scope.pushVariable = function(variablename, variablevalue, variabletype, variablefound) {
+            var pushVariable = function(variablename, variableValue, variableType, variablefound) {
                 //First clean away single or double quotation marks at the start and end of the variable name.
-                variablevalue = $filter('trimquotes')(variablevalue);
+                variableValue = $filter('trimquotes')(variableValue);
                 
                 //Append single quotation marks in case the variable is of text type:
-                if(variabletype === 'string') {
-                    variablevalue = "'" + variablevalue + "'";
-                }
-                else if(variabletype === 'date') {
-                    variablevalue = "'" + variablevalue + "'";
-                }
-                else if(variabletype === 'bool' || variabletype === 'trueOnly') {
-                    if(eval(variablevalue)) {
-                        variablevalue = true;
+                if(variableType === 'string') {
+                    variableValue = "'" + variableValue + "'";
+                }
+                else if(variableType === 'date') {
+                    variableValue = "'" + variableValue + "'";
+                }
+                else if(variableType === 'bool' || variableType === 'trueOnly') {
+                    if(eval(variableValue)) {
+                        variableValue = true;
                     }
                     else {    
-                        variablevalue = false;
+                        variableValue = false;
                     }
                 }
-                else if(variabletype === "int" || variabletype === "number") {
-                    variablevalue = Number(variablevalue);
+                else if(variableType === "int" || variableType === "number") {
+                    variableValue = Number(variableValue);
                 }
                 else{
-                    $log.warn("unknown datatype:" + variabletype);
+                    $log.warn("unknown datatype:" + variableType);
                 }
                  
                 
-                //Make sure that the variablevalue does not contain a dollar sign anywhere 
+                //Make sure that the variableValue does not contain a dollar sign anywhere 
                 //- this would potentially mess up later use of the variable:
-//                if(angular.isDefined(variablevalue) 
-//                        && variablevalue !== null
-//                        && variablevalue.indexOf("$") !== -1 ) {
-//                    variablevalue = variablevalue.replace(/\\$/,"");
+//                if(angular.isDefined(variableValue) 
+//                        && variableValue !== null
+//                        && variableValue.indexOf("$") !== -1 ) {
+//                    variableValue = variableValue.replace(/\\$/,"");
 //                }
                 
                 //TODO:
                 //Also clean away instructions that might be erroneusly evalutated in javascript
 
-                variables.push({variablename:variablename,
-                                variablevalue:variablevalue,
-                                variabletype:variabletype,
+                variables[variablename] = {
+                                variableValue:variableValue,
+                                variableType:variableType,
                                 hasValue:variablefound
-                            });
+                            };
             };
             
-            TrackerRuleVariableFactory.getProgramRuleVariables($scope.currentEvent.program).then(function(programVariables){
+            TrackerRuleVariableFactory.getProgramRuleVariables(programid).then(function(programVariables){
 
                 // The following section will need a different implementation for event capture:
                 var allEventsSorted = [];
-                var currentEvent = $scope.currentEvent;
+                var currentEvent = executingEvent;
                 var eventsSortedPerProgramStage = [];
                 
-                for(var key in $scope.eventsByStage){
-                    if($scope.eventsByStage.hasOwnProperty(key)){
+                for(var key in allEventsByStage){
+                    if(allEventsByStage.hasOwnProperty(key)){
                         eventsSortedPerProgramStage[key] = [];
-                        angular.forEach($scope.eventsByStage[key], function(event){
+                        angular.forEach(allEventsByStage[key], function(event){
                             allEventsSorted.push(event);
                             eventsSortedPerProgramStage[key].push(event);
                         });
@@ -1846,12 +1846,12 @@
                 }
                 allEventsSorted = orderByFilter(allEventsSorted, '-sortingDate').reverse(); 
                 
-                var allDes = {};
-                angular.forEach($scope.programStages, function(programStage){
-                    angular.forEach(programStage.programStageDataElements, function(dataElement) {
-                        allDes[dataElement.dataElement.id] = dataElement;
-                    });
-                });
+                var allDes = allDataElements;
+//                angular.forEach($scope.programStages, function(programStage){
+//                    angular.forEach(programStage.programStageDataElements, function(dataElement) {
+//                        allDes[dataElement.dataElement.id] = dataElement;
+//                    });
+//                });
                 //End of region that neeeds specific implementation for event capture
                 
                 angular.forEach(programVariables, function(programVariable) {
@@ -1862,7 +1862,7 @@
                                 if(angular.isDefined(event[programVariable.dataElement.id])
                                         && event[programVariable.dataElement.id] !== null ){
                                     valueFound = true;
-                                    $scope.pushVariable(programVariable.name, event[programVariable.dataElement.id], allDes[programVariable.dataElement.id].dataElement.type, valueFound );
+                                    pushVariable(programVariable.name, event[programVariable.dataElement.id], allDes[programVariable.dataElement.id].dataElement.type, valueFound );
                                 }
                             });
                         } else {
@@ -1877,7 +1877,7 @@
                             if(angular.isDefined(event[programVariable.dataElement.id])
                                     && event[programVariable.dataElement.id] !== null ){
                                 valueFound = true;
-                                 $scope.pushVariable(programVariable.name, event[programVariable.dataElement.id], allDes[programVariable.dataElement.id].dataElement.type, valueFound );
+                                 pushVariable(programVariable.name, event[programVariable.dataElement.id], allDes[programVariable.dataElement.id].dataElement.type, valueFound );
                              }
                         });
                     }
@@ -1885,7 +1885,7 @@
                         if(angular.isDefined(currentEvent[programVariable.dataElement.id])
                                 && currentEvent[programVariable.dataElement.id] !== null ){
                             valueFound = true;
-                            $scope.pushVariable(programVariable.name, currentEvent[programVariable.dataElement.id], allDes[programVariable.dataElement.id].dataElement.type, valueFound );
+                            pushVariable(programVariable.name, currentEvent[programVariable.dataElement.id], allDes[programVariable.dataElement.id].dataElement.type, valueFound );
                         }      
                     }
                     else if(programVariable.programRuleVariableSourceType === "DATAELEMENT_PREVIOUS_EVENT"){
@@ -1904,21 +1904,20 @@
                                 else if(allEventsSorted[i] === currentEvent) {
                                     //We have iterated to the newest event - store the last collected variable value - if any is found:
                                     if(valueFound) {
-                                        $scope.pushVariable(programVariable.name, previousvalue, allDes[programVariable.dataElement.id].dataElement.type, 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($scope.selectedEntity.attributes , function(attribute) {
+                        angular.forEach(selectedEntity.attributes , function(attribute) {
                             if(!valueFound) {
                                 if(attribute.attribute === programVariable.trackedEntityAttribute.id) {
                                     valueFound = true;
-                                    $scope.pushVariable(programVariable.name, attribute.value, attribute.type, valueFound );
+                                    pushVariable(programVariable.name, attribute.value, attribute.type, valueFound );
                                 }
                             }
                         });
@@ -1932,7 +1931,7 @@
                             numberOfEvents = eventsSortedPerProgramStage[programVariable.programStage.id].length;
                         }
                         valueFound = true;
-                        $scope.pushVariable(programVariable.name, numberOfEvents, 'int', valueFound );
+                        pushVariable(programVariable.name, numberOfEvents, 'int', valueFound );
                     }
                     else {
                         //Missing handing of ruletype
@@ -1945,22 +1944,22 @@
                         if(programVariable.dataElement) {
                             var dataElement = allDes[programVariable.dataElement.id];
                             if( dataElement ) {
-                                $scope.pushVariable(programVariable.name, "", dataElement.dataElement.type );
+                                pushVariable(programVariable.name, "", dataElement.dataElement.type );
                             } 
                             else {
                                 $log.warn("Variable #{" + programVariable.name + "} is linked to a dataelement that is not part of the program");
-                                $scope.pushVariable(programVariable.name, "", "string" );
+                                pushVariable(programVariable.name, "", "string" );
                             }
                         }
                         else {
-                            $scope.pushVariable(programVariable.name, "", "string" );
+                            pushVariable(programVariable.name, "", "string" );
                         }
                     }
                 });
 
                 //add context variables:
                 //last parameter "valuefound" is always true for event date
-                $scope.pushVariable('eventdate', currentEvent.eventDate, 'date', true );
+                pushVariable('eventdate', executingEvent.eventDate, 'date', true );
                 
                 thePromisedVariables.resolve(variables);
             });
@@ -1975,16 +1974,15 @@
 /* service for executing tracker rules and broadcasting results */
 .service('TrackerRulesExecutionService', function(TrackerRulesFactory,VariableService, $rootScope, $log, $filter, orderByFilter){
     return {
-        executeRules: function($scope) {
+        executeRules: function(programid, executingEvent, allEventsByStage, allDataElements, selectedEntity) {
             //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 variablesWithValueHash = {};
                     
-            $scope.replaceVariables = function(expression) {
+            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) {
@@ -1998,7 +1996,7 @@
                         if(angular.isDefined(variablesHash[variablepresent])) {
                             //Replace all occurrences of the variable name(hence using regex replacement):
                             expression = expression.replace(new RegExp("#{" + variablepresent + "}", 'g'),
-                                variablesHash[variablepresent]);
+                                variablesHash[variablepresent].variableValue);
                         }
                         else {
                             $log.warn("Expression " + expression + " conains variable " + variablepresent 
@@ -2010,7 +2008,7 @@
                 return expression;
             };
             
-            $scope.runDhisFunctions = function(expression) {
+            var runDhisFunctions = function(expression) {
                 //Called from "runExpression". Only proceed with this logic in case there seems to be dhis function calls: "dhis." is present.
                 if(angular.isDefined(expression) && expression.indexOf("dhis.") !== -1){   
                     var dhisFunctions = [{name:"dhis.daysbetween",parameters:2},
@@ -2042,7 +2040,7 @@
                             //In case the function call is nested, the parameter itself contains an expression, run the expression.
                             if(angular.isDefined(parameters)) {
                                 for (var i = 0; i < parameters.length; i++) {
-                                    parameters[i] = $scope.runExpression(parameters[i],dhisFunction.name,"parameter:" + i);
+                                    parameters[i] = runExpression(parameters[i],dhisFunction.name,"parameter:" + i);
                                 }
                             }
 
@@ -2073,7 +2071,7 @@
                             else if(dhisFunction.name === "dhis.hasValue")
                             {
                                 //"evaluate" hasvalue to true or false:
-                                if(variablesWithValueHash[parameters[0]]){
+                                if(variablesHash[parameters[0]].hasValue){
                                     expression = expression.replace(callToThisFunction, 'true');
                                 } else {
                                     expression = expression.replace(callToThisFunction, 'false');
@@ -2095,14 +2093,14 @@
                 return expression;
             };
             
-            $scope.runExpression = function(expression, beforereplacement, identifier ){
+            var runExpression = function(expression, beforereplacement, identifier ){
                 //determine if expression is true, and actions should be effectuated
                 //If DEBUG mode, use try catch and report errors. If not, omit the heavy try-catch loop.:
                 var answer = false;
                 if(debug) {
                     try{
                         
-                        var dhisfunctionsevaluated = $scope.runDhisFunctions(expression);
+                        var dhisfunctionsevaluated = runDhisFunctions(expression);
                         answer = eval(dhisfunctionsevaluated);
 
                         if(verbose)
@@ -2117,34 +2115,30 @@
                 }
                 else {
                     //Just run the expression. This is much faster than the debug route: http://jsperf.com/try-catch-block-loop-performance-comparison
-                    var dhisfunctionsevaluated = $scope.runDhisFunctions(expression);
+                    var dhisfunctionsevaluated = runDhisFunctions(expression);
                     answer = eval(dhisfunctionsevaluated);
                 }
                 return answer;
             };
             
             
-            VariableService.getVariables($scope).then(function(variables){
-                TrackerRulesFactory.getProgramStageRules($scope.selectedProgram.id, $scope.currentStage.id).then(function(rules){
+            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');
-
-                    //Make a variables hash to allow direct lookup:
-                    angular.forEach(variables, function(variable) {
-                        variablesHash[variable.variablename] = variable.variablevalue;
-                    });
                     
-                    //Make a variables-exists/hasvalue hash to allow direct lookup:
-                    angular.forEach(variables, function(variable) {
-                        variablesWithValueHash[variable.variablename] = variable.hasValue;
-                    });
+                    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 )){
+                        if(angular.isUndefined( $rootScope.ruleeffects ) ) {
                             $rootScope.ruleeffects = {};
                         }
+                            
+                        if(angular.isUndefined( $rootScope.ruleeffects[executingEvent.event] )){
+                            $rootScope.ruleeffects[executingEvent.event] = {};
+                        }
 
                         var updatedEffectsExits = false;
 
@@ -2155,18 +2149,18 @@
                             //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 = $scope.replaceVariables(expression);
+                                    expression = replaceVariables(expression);
                                 }
                                 //run expression:
-                                ruleEffective = $scope.runExpression(expression, rule.condition, "rule:" + rule.id);
+                                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.actions, function(action){
                                 //In case the effect-hash is not populated, add entries
-                                if(angular.isUndefined( $rootScope.ruleeffects[action.id] )){
-                                    $rootScope.ruleeffects[action.id] =  {
+                                if(angular.isUndefined( $rootScope.ruleeffects[executingEvent.event][action.id] )){
+                                    $rootScope.ruleeffects[executingEvent.event][action.id] =  {
                                         id:action.id,
                                         location:action.location, 
                                         action:action.programRuleActionType,
@@ -2186,56 +2180,56 @@
                                     //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 nameWithoutDollarSign = action.data.replace('#{','').replace('}','');
-                                    if(angular.isDefined(variablesHash[nameWithoutDollarSign]))
+                                    var nameWithoutBrackets = action.data.replace('#{','').replace('}','');
+                                    if(angular.isDefined(variablesHash[nameWithoutBrackets]))
                                     {
                                         //The variable exists, and is replaced with its corresponding value
-                                        $rootScope.ruleeffects[action.id].data =
-                                            variablesHash[nameWithoutDollarSign];
+                                        $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[action.id].data = $scope.replaceVariables(action.data);
+                                        $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[action.id].data = $scope.runExpression($rootScope.ruleeffects[action.id].data, action.data, "action:" + action.id);
+                                        $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[action.id].ineffect != ruleEffective)
+                                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[action.id].ineffect = ruleEffective;
+                                    $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[action.id].action === "ASSIGNVARIABLE" && $rootScope.ruleeffects[action.id].ineffect){
+                                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[action.id].content.replace("#{","").replace("}","");
+                                    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] !== $rootScope.ruleeffects[action.id].data){
+                                    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] = $rootScope.ruleeffects[action.id].data;
+                                        variablesHash[variabletoassign].variableValue = $rootScope.ruleeffects[executingEvent.event][action.id].data;
                                     }
                                 }
                             });
                         });
 
-                        //Broadcast rules finished if there was any actual changes.
+                        //Broadcast rules finished if there was any actual changes to the event.
                         if(updatedEffectsExits){
-                            $rootScope.$broadcast("ruleeffectsupdated");
+                            $rootScope.$broadcast("ruleeffectsupdated", { event: executingEvent.event });
                         }
                     }