← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 18883: Add UI for ProgramRule object.

 

------------------------------------------------------------
revno: 18883
committer: Tran Chau<tran.hispvietnam@xxxxxxxxx>
branch nick: dhis2
timestamp: Sat 2015-04-11 20:18:25 +0700
message:
  Add UI for ProgramRule object.
added:
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonProgramRule.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/GetProgramRuleAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/GetProgramRuleListAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/ShowAddProgramRuleFormAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/ValidateProgramRuleAction.java
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramRule.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/javascript/programRule.js
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programRule.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/updateProgramRule.vm
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/programrule/ProgramRuleService.java
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/programrule/ProgramRuleStore.java
  dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/programrule/DefaultProgramRuleService.java
  dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/programrule/hibernate/HibernateProgramRuleStore.java
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/validationRules.js
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/resources/META-INF/dhis/beans.xml
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/resources/org/hisp/dhis/trackedentity/i18n_module.properties
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/resources/struts.xml
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramStageSectionForm.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/javascript/program.js
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programList.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/updateProgramStageSectionForm.vm
  dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/resources/org/hisp/dhis/user/i18n_module.properties


--
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-api/src/main/java/org/hisp/dhis/programrule/ProgramRuleService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/programrule/ProgramRuleService.java	2015-03-13 08:24:36 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/programrule/ProgramRuleService.java	2015-04-11 13:18:25 +0000
@@ -70,6 +70,15 @@
     ProgramRule getProgramRule( int id );
 
     /**
+     * Returns a {@link ProgramRule}.
+     *
+     * @param name the name of the ProgramRule to return.
+     * @param program {@link Program}.
+     * @return the ProgramRule with the given name
+     */
+    ProgramRule getProgramRuleByName( String name, Program program );
+
+    /**
      * Returns all {@link ProgramRule}.
      *
      * @return a collection of all ProgramRule, or an empty collection if
@@ -84,4 +93,13 @@
      * @return ProgramRule list
      */
     Collection<ProgramRule> getProgramRule( Program program );
+
+    /**
+     * Get validation by {@link Program}
+     *
+     * @param program Program
+     * @param key Search Program Rule by key
+     * @return ProgramRule list
+     */
+    Collection<ProgramRule> getProgramRules( Program program, String key );
 }

=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/programrule/ProgramRuleStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/programrule/ProgramRuleStore.java	2015-03-13 08:24:36 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/programrule/ProgramRuleStore.java	2015-04-11 13:18:25 +0000
@@ -48,4 +48,22 @@
      * @return ProgramRuleVariable list
      */
     Collection<ProgramRule> get( Program program );
+    
+    /**
+     * Returns a {@link ProgramRule}.
+     *
+     * @param name the name of the ProgramRule to return.
+     * @param program {@link Program}.
+     * @return the ProgramRule with the given name
+     */
+    ProgramRule getByName( String name, Program program );
+
+    /**
+     * Get validation by {@link Program}
+     *
+     * @param program Program
+     * @param key Search Program Rule by key
+     * @return ProgramRule list
+     */
+    Collection<ProgramRule> get( Program program, String key );
 }

=== modified file 'dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/programrule/DefaultProgramRuleService.java'
--- dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/programrule/DefaultProgramRuleService.java	2015-03-13 08:24:36 +0000
+++ dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/programrule/DefaultProgramRuleService.java	2015-04-11 13:18:25 +0000
@@ -78,7 +78,13 @@
     {
         return programRuleStore.get( id );
     }
-
+    
+    @Override
+    public ProgramRule getProgramRuleByName( String name, Program program )
+    {
+        return programRuleStore.getByName( name, program );
+    }
+    
     @Override
     public Collection<ProgramRule> getAllProgramRule()
     {
@@ -90,4 +96,10 @@
     {
         return programRuleStore.get( program );
     }
+    
+    @Override
+    public Collection<ProgramRule> getProgramRules( Program program, String key )
+    {
+        return programRuleStore.get( program, key );
+    }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/programrule/hibernate/HibernateProgramRuleStore.java'
--- dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/programrule/hibernate/HibernateProgramRuleStore.java	2015-03-13 08:24:36 +0000
+++ dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/programrule/hibernate/HibernateProgramRuleStore.java	2015-04-11 13:18:25 +0000
@@ -30,6 +30,7 @@
 
 import java.util.Collection;
 
+import org.hibernate.criterion.Order;
 import org.hibernate.criterion.Restrictions;
 import org.hisp.dhis.common.hibernate.HibernateIdentifiableObjectStore;
 import org.hisp.dhis.program.Program;
@@ -49,4 +50,22 @@
     {
         return getCriteria( Restrictions.eq( "program", program ) ).list();
     }
+    
+    @Override
+    public ProgramRule getByName( String name, Program program )
+    {
+        return (ProgramRule) getCriteria( Restrictions.eq( "name", name ), Restrictions.eq( "program", program ) )
+            .uniqueResult();
+    }
+    
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public Collection<ProgramRule> get( Program program, String key )
+    {
+        return getSharingCriteria()
+            .add( Restrictions.eq( "program", program ) )
+            .add( Restrictions.like( "name", "%" + key + "%" ).ignoreCase())
+            .addOrder( Order.asc( "name" ) )
+            .list();
+    }
 }

=== added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonProgramRule.vm'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonProgramRule.vm	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/ajax/jsonProgramRule.vm	2015-04-11 13:18:25 +0000
@@ -0,0 +1,8 @@
+{ "programRule": 
+  {
+    "id": "$!{programRule.id}",
+    "uid": "$!{programRule.uid}",
+    "name": "$!encoder.jsonEncode( ${programRule.displayName} )",
+    "description": "$!encoder.jsonEncode( ${programRule.description} )"
+  }
+}

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/validationRules.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/validationRules.js	2015-04-08 23:26:45 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/validationRules.js	2015-04-11 13:18:25 +0000
@@ -498,7 +498,21 @@
             "number" : true
         }
     },
-    "trackedEntityInstanceReminder" : {
+    "programRule" : {
+        "name" : {
+            "required" : true,
+            "rangelength" : [ 2,160 ]
+        },
+        "description" : {
+            "required" : true,
+            "rangelength" : [ 2, 160 ]
+        },
+        "condition" : {
+            "required" : true,
+            "rangelength" : [ 2, 255 ]
+        }
+    },
+	"trackedEntityInstanceReminder" : {
         "name" : {
             "required" : true,
             "rangelength" : [2,160]

=== added directory 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule'
=== added file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/GetProgramRuleAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/GetProgramRuleAction.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/GetProgramRuleAction.java	2015-04-11 13:18:25 +0000
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2004-2014, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.hisp.dhis.trackedentity.action.programrule;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hisp.dhis.programrule.ProgramRule;
+import org.hisp.dhis.programrule.ProgramRuleService;
+import org.hisp.dhis.programrule.ProgramRuleVariable;
+import org.hisp.dhis.programrule.ProgramRuleVariableService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Chau Thu Tran
+ *
+ * @version $ ValidationProgramRuleAction.java Mar 29, 2015 10:19:42 PM $
+ */
+public class GetProgramRuleAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private ProgramRuleService programRuleService;
+    
+    @Autowired
+    private ProgramRuleVariableService variableService;
+
+    // -------------------------------------------------------------------------
+    // Input/Output
+    // -------------------------------------------------------------------------
+
+    private Integer id;
+
+    public void setId( Integer id )
+    {
+        this.id = id;
+    }
+
+    private ProgramRule programRule;
+
+    public ProgramRule getProgramRule()
+    {
+        return programRule;
+    }
+
+    private List<ProgramRuleVariable> ruleVariables;
+
+    public List<ProgramRuleVariable> getRuleVariables()
+    {
+        return ruleVariables;
+    }
+    
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    @Override
+    public String execute()
+        throws Exception
+    {
+        programRule = programRuleService.getProgramRule( id );
+       
+        ruleVariables = new ArrayList<>( variableService.getProgramRuleVariable( programRule.getProgram() ));
+        
+        return SUCCESS;
+    }
+
+}

=== added file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/GetProgramRuleListAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/GetProgramRuleListAction.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/GetProgramRuleListAction.java	2015-04-11 13:18:25 +0000
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2004-2014, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.hisp.dhis.trackedentity.action.programrule;
+
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hisp.dhis.program.Program;
+import org.hisp.dhis.program.ProgramService;
+import org.hisp.dhis.programrule.ProgramRule;
+import org.hisp.dhis.programrule.ProgramRuleService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Chau Thu Tran
+ *
+ * @version $ GetProgramRuleListAction.java Mar 29, 2015 11:23:11 PM $
+ */
+public class GetProgramRuleListAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private ProgramService programService;
+
+    @Autowired
+    private ProgramRuleService programRuleService;
+
+    // -------------------------------------------------------------------------
+    // Input/Output
+    // -------------------------------------------------------------------------
+
+    private Integer id;
+
+    public void setId( Integer id )
+    {
+        this.id = id;
+    }
+
+    private List<ProgramRule> programRules;
+
+    public List<ProgramRule> getProgramRules()
+    {
+        return programRules;
+    }
+
+    private Program program;
+
+    public Program getProgram()
+    {
+        return program;
+    }
+
+    private String key;
+
+    public String getKey()
+    {
+        return key;
+    }
+
+    public void setKey( String key )
+    {
+        this.key = key;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    @Override
+    public String execute()
+        throws Exception
+    {
+        program = programService.getProgram( id );
+
+        if ( isNotBlank( key ) )
+        {
+            programRules = new ArrayList<ProgramRule>( programRuleService.getProgramRules( program, key ) );
+        }
+        else
+        {
+            programRules = new ArrayList<ProgramRule>( programRuleService.getProgramRule( program ) );
+        }
+
+        return SUCCESS;
+    }
+}

=== added file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/ShowAddProgramRuleFormAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/ShowAddProgramRuleFormAction.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/ShowAddProgramRuleFormAction.java	2015-04-11 13:18:25 +0000
@@ -0,0 +1,103 @@
+package org.hisp.dhis.trackedentity.action.programrule;
+
+/*
+ * Copyright (c) 2004-2015, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hisp.dhis.program.Program;
+import org.hisp.dhis.program.ProgramService;
+import org.hisp.dhis.programrule.ProgramRuleVariable;
+import org.hisp.dhis.programrule.ProgramRuleVariableService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Tran Chau
+ * @version $Id$
+ */
+public class ShowAddProgramRuleFormAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private ProgramService programService;
+    
+    @Autowired
+    private ProgramRuleVariableService variableService;
+
+    // -------------------------------------------------------------------------
+    // Input/Output
+    // -------------------------------------------------------------------------
+
+    private int id;
+
+    public int getId()
+    {
+        return id;
+    }
+
+    public void setId( int id )
+    {
+        this.id = id;
+    }
+
+    private Program program;
+
+    public Program getProgram()
+    {
+        return program;
+    }
+
+    private List<ProgramRuleVariable> ruleVariables;
+
+    public List<ProgramRuleVariable> getRuleVariables()
+    {
+        return ruleVariables;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    @Override
+    public String execute()
+        throws Exception
+    {
+        program = programService.getProgram( id );
+
+        ruleVariables = new ArrayList<>( variableService.getProgramRuleVariable( program ));
+            
+        return SUCCESS;
+    }
+}

=== added file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/ValidateProgramRuleAction.java'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/ValidateProgramRuleAction.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/java/org/hisp/dhis/trackedentity/action/programrule/ValidateProgramRuleAction.java	2015-04-11 13:18:25 +0000
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2004-2014, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.hisp.dhis.trackedentity.action.programrule;
+
+import org.hisp.dhis.i18n.I18n;
+import org.hisp.dhis.program.Program;
+import org.hisp.dhis.program.ProgramService;
+import org.hisp.dhis.programrule.ProgramRule;
+import org.hisp.dhis.programrule.ProgramRuleService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.opensymphony.xwork2.Action;
+
+/**
+ * @author Chau Thu Tran
+ *
+ * @version $ ValidateProgramRuleAction.java Mar 29, 2015 10:19:42 PM $
+ */
+public class ValidateProgramRuleAction
+    implements Action
+{
+    // -------------------------------------------------------------------------
+    // Dependencies
+    // -------------------------------------------------------------------------
+
+    @Autowired
+    private ProgramRuleService programRuleService;
+
+    @Autowired
+    private ProgramService programService;
+
+    // -------------------------------------------------------------------------
+    // Input/Output
+    // -------------------------------------------------------------------------
+
+    private Integer id;
+
+    public void setId( Integer id )
+    {
+        this.id = id;
+    }
+
+    private String name;
+
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+
+    private Integer programId;
+
+    public void setProgramId( Integer programId )
+    {
+        this.programId = programId;
+    }
+
+    private String message;
+
+    public String getMessage()
+    {
+        return message;
+    }
+
+    private I18n i18n;
+
+    public void setI18n( I18n i18n )
+    {
+        this.i18n = i18n;
+    }
+
+    // -------------------------------------------------------------------------
+    // Action implementation
+    // -------------------------------------------------------------------------
+
+    @Override
+    public String execute()
+        throws Exception
+    {
+        Program program = programService.getProgram( programId );
+
+        ProgramRule match = programRuleService.getProgramRuleByName( name, program );
+
+        if ( match != null && (id == null || match.getId() != id.intValue()) )
+        {
+            message = i18n.getString( "name_exists" );
+
+            return ERROR;
+        }
+
+        // ---------------------------------------------------------------------
+        // Validation success
+        // ---------------------------------------------------------------------
+
+        message = i18n.getString( "everything_is_ok" );
+
+        return SUCCESS;
+    }
+
+}

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/resources/META-INF/dhis/beans.xml	2015-03-31 09:52:30 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/resources/META-INF/dhis/beans.xml	2015-04-11 13:18:25 +0000
@@ -1167,5 +1167,32 @@
     class="org.hisp.dhis.trackedentity.action.trackedentity.ValidateTrackedEntityAction"
     scope="prototype">
   </bean>
+  
+  <!-- Program Rule -->
+  
+  <bean
+    id="org.hisp.dhis.trackedentity.action.programrule.ValidateProgramRuleAction"
+    class="org.hisp.dhis.trackedentity.action.programrule.ValidateProgramRuleAction"
+    scope="prototype">
+  </bean>
+   
+   <bean
+    id="org.hisp.dhis.trackedentity.action.programrule.GetProgramRuleAction"
+    class="org.hisp.dhis.trackedentity.action.programrule.GetProgramRuleAction"
+    scope="prototype">
+  </bean>
+     
+  <bean
+    id="org.hisp.dhis.trackedentity.action.programrule.GetProgramRuleListAction"
+    class="org.hisp.dhis.trackedentity.action.programrule.GetProgramRuleListAction"
+    scope="prototype">
+  </bean>
+  
+  <bean
+    id="org.hisp.dhis.trackedentity.action.programrule.ShowAddProgramRuleFormAction"
+    class="org.hisp.dhis.trackedentity.action.programrule.ShowAddProgramRuleFormAction"
+    scope="prototype">
+  </bean>
+  
 
 </beans>
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/resources/org/hisp/dhis/trackedentity/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/resources/org/hisp/dhis/trackedentity/i18n_module.properties	2015-03-31 09:43:34 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/resources/org/hisp/dhis/trackedentity/i18n_module.properties	2015-04-11 13:18:25 +0000
@@ -510,4 +510,31 @@
 expression_is_not_well_formed = Expression is not well-formed
 program_variables = Program variables
 custom_standard_interval = Custom standard interval
-period_type = Period type
\ No newline at end of file
+period_type = Period type
+create_new_program_rule = Create new program rule
+program_rule_details = Program rule details
+source_fields = Source fields
+expression_evaluate_the_source_fields = Expression - evaluate the source fields
+add_source_field = Add source field
+actions_that_is_executed_when_expression_is_true = Actions that is executed when expression is true
+display_text = Display text
+shows_a_key_data_box = Shows a key data box
+hide_field = Hide field
+assign_variable = Assign variable
+show_warning = Show warning
+show_error = Show error
+view_program_rule = View program rules
+program_rule_management = Program rule management
+create_new_program_rule = Create new program rule
+program_rule_details = Program rule details
+confirm_delete_program_rule = Are you sure you want to delete program rule?
+source_program_stage = Source program stage
+source_dataElement = Source DataElement
+variable_name = Variable name
+data_element_newest_event_program_stage = Data element newest event program stage
+data_element_newest_event_program = Data element newest event program
+add_source_field = Add source field
+add_more_action = Add more action
+source_type = Source type
+please_enter_action_description = Please enter action description
+confirm_delete_program_rule = Are you sure you want to delete program rule?
\ No newline at end of file

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/resources/struts.xml'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/resources/struts.xml	2015-04-08 04:43:57 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/resources/struts.xml	2015-04-11 13:18:25 +0000
@@ -1274,6 +1274,49 @@
         /dhis-web-commons/ajax/jsonResponseError.vm
       </result>
     </action>
+    
+    <!-- Program Rule -->    
+    
+     <action name="programRule"
+      class="org.hisp.dhis.trackedentity.action.programrule.GetProgramRuleListAction">
+      <result name="success" type="velocity">/main.vm</result>
+      <param name="page">/dhis-web-maintenance-program/programRule.vm</param>
+      <param name="menu">/dhis-web-maintenance-program/menu.vm</param>
+      <param name="javascripts">javascript/programRule.js</param>
+      <param name="requiredAuthorities">F_PROGRAM_RULE_MANAGEMENT</param>
+    </action>
+    
+    <action name="showAddProgramRuleForm" class="org.hisp.dhis.trackedentity.action.programrule.ShowAddProgramRuleFormAction">
+      <result name="success" type="velocity">/main.vm</result>
+      <param name="page">/dhis-web-maintenance-program/addProgramRule.vm</param>
+      <param name="javascripts">javascript/programRule.js</param>
+      <param name="requiredAuthorities">F_PROGRAM_RULE_ADD</param>
+    </action> 
+    
+    <action name="showUpdateProgramRuleForm" class="org.hisp.dhis.trackedentity.action.programrule.GetProgramRuleAction">
+      <result name="success" type="velocity">/main.vm</result>
+      <param name="page">/dhis-web-maintenance-program/updateProgramRule.vm</param>
+      <param name="javascripts">javascript/programRule.js</param>
+      <param name="requiredAuthorities">F_PROGRAM_RULE_UPDATE</param>
+    </action>
+    
+    <action name="validateProgramRule"
+      class="org.hisp.dhis.trackedentity.action.programrule.ValidateProgramRuleAction">
+      <result name="success" type="velocity-json">
+        /dhis-web-commons/ajax/jsonResponseSuccess.vm
+      </result>
+      <result name="error" type="velocity-json">
+        /dhis-web-commons/ajax/jsonResponseError.vm
+      </result>
+    </action> 
+    
+    <action name="getProgramRule"
+      class="org.hisp.dhis.trackedentity.action.programrule.GetProgramRuleAction">
+      <result name="success" type="velocity-json">
+        /dhis-web-commons/ajax/jsonProgramRule.vm
+      </result>
+      <param name="onExceptionReturn">plainTextError</param>
+    </action>
 
   </package>
 </struts>

=== added file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramRule.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramRule.vm	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramRule.vm	2015-04-11 13:18:25 +0000
@@ -0,0 +1,194 @@
+<script>
+	
+	jQuery( document ).ready( function()
+	{	
+		validation2( 'programRuleForm', function( form )
+		{
+			validateProgramRule();
+		},{
+			'beforeValidateHandler' : function()
+			{
+				if( $("#actionTB tr").length == 0 )
+				{
+					setFieldValue('hasAction','');
+				}
+				else
+				{
+					setFieldValue('hasAction','yes');
+				}
+			},
+			'rules' : getValidationRules( "programRule" )
+		});
+		
+		checkValueIsExist( "name", "validateProgramRule.action",{programId:"$program.id"}  );
+		removeDuplicateOptions();
+	});
+	
+	var i18n_add_source_field = '$encoder.jsEscape( $i18n.getString( "add_source_field" ) , "'" )';
+	var i18n_display_text = '$encoder.jsEscape( $i18n.getString( "display_text" ) , "'" )';
+	var i18n_shows_a_key_data_box = '$encoder.jsEscape( $i18n.getString( "shows_a_key_data_box" ) , "'" )';
+	var i18n_hide_field = '$encoder.jsEscape( $i18n.getString( "hide_field" ) , "'" )';
+	var i18n_assign_variable = '$encoder.jsEscape( $i18n.getString( "assign_variable" ) , "'" )';
+	var i18n_show_warning = '$encoder.jsEscape( $i18n.getString( "show_warning" ) , "'" )';
+	var i18n_show_error = '$encoder.jsEscape( $i18n.getString( "show_error" ) , "'" )';
+	var i18n_this_field_is_required = '$encoder.jsEscape( $i18n.getString( "this_field_is_required" ) , "'")';
+	var i18n_name_in_use = '$encoder.jsEscape( $i18n.getString( "name_in_use" ) , "'")';
+	var i18n_please_enter_action_description = '$encoder.jsEscape( $i18n.getString( "please_enter_action_description" ) , "'")';
+	var i18n_confirm_delete = '$encoder.jsEscape( $i18n.getString( "confirm_delete_program_rule" ) , "'")';
+</script>
+
+<h3>$i18n.getString( "create_new_program_rule" )</h3>
+									
+<form id="programRuleForm" name="programRuleForm" action="addProgramRule.action" method="post" class="inputForm">
+
+<input type='hidden' id='programId' name='programId' value="$program.uid" />
+<input type='hidden' id='programLocalId' name='programLocalId' value="$program.id" />
+
+<table width="70%">
+	<col width="10%">
+	<col width="40%">
+	<col width="25%">
+	<col width="25%">
+	<thead>
+      <tr>
+        <th colspan="4">$i18n.getString( "program_rule_details" )</th>
+      </tr>
+    </thead>
+    
+	<tbody>
+		<tr>
+			<td><label for="name">$i18n.getString( "name" ) <em title="$i18n.getString( "required" )" class="required">*</em></label></td>
+			<td colspan='3'><input type="text" id="name" name="name" style="width:98%" ></td>
+		</tr>	
+		
+		<tr>
+			<td><label for="description">$i18n.getString( "description" ) <em title="$i18n.getString( "required" )" class="required">*</em></label></td>
+			<td colspan='3'><input type="text" id="description" name="description" style="width:98%" /></td>
+		</tr>
+		
+		<tr>
+			<th colspan="2">1. $i18n.getString("source_fields")</th>
+			<th colspan="2">2. $i18n.getString("expression_evaluate_the_source_fields") <em title="$i18n.getString( "required" )" class="required">*</em></th>
+		</tr>
+		<tr>
+			<td colspan='2'>
+				<fieldset style="height:100%;">
+					<div style="height:80px;border:1px solid black; overflow: auto;">
+						<table id='sourceFieldList' style="height:80px;width:100%" >
+							<col width="50%" />
+							<col width="50%" />
+							#set($idx = 0 )
+							#foreach($ruleVariable in $ruleVariables)
+								#set( $json_Data='{"name":"' + $ruleVariable.name + '"'
+									+ ',"sourceType":"' + $ruleVariable.sourceType + '"'
+									+ ',"dataElement":{ "id":"' + $ruleVariable.dataElement.id + '"}'
+									+ ',"program":{"id":"' + $ruleVariable.program.id + '"}'
+									+ ',"programStage":{"id":"' + "$!ruleVariable.programStage.id" + '"}}' )
+								#set($clazz = "listAlternateRow")
+								#if( $idx % 2 == 0 )
+									#set($clazz = "listRow")
+								#end		
+								#set($idx = $idx + 1 )
+								<tr class="$clazz" jsonData='$json_Data' id="$ruleVariable.uid">
+									<td>$encoder.htmlEncode($ruleVariable.dataElement.displayName)</td>
+									<td><input type='button' deId='$ruleVariable.dataElement.uid' realValue='$ruleVariable.name' value='$$ruleVariable.name' style='width:150px;' onclick='insertVariable(this)'/></td>
+								</tr>
+							#end
+						</table>
+					</div><br>
+					<input type="button" id="addMoreVariableBtn" value="+ $i18n.getString('add_source_field')" onclick="javascript:addSourceFieldForm();"/>
+				</fieldset>
+			</td>			
+			<td colspan='2'>
+				<fieldset>
+					<textarea size="10" id='condition' name='condition' style="width:98%;border:none"></textarea>
+				</fieldset>
+			</td>
+		</tr>
+		
+		<tr>
+			<th colspan="3">3. $i18n.getString("actions_that_is_executed_when_expression_is_true") <em title="$i18n.getString( "required" )" class="required">*</em>
+			</th>
+			<td>
+				<input type="hidden" id="hasAction" name="hasAction" class="{validate:{required:true}}" >
+			</td>
+		</tr>
+		<tr>
+			<td colspan="4">
+				<table width="100%">
+					<col width="20%">
+					<col width="60%">
+					<col width="20%">
+					<tbody id='actionTB'></tbody>
+					<tr>
+						<td><input type="button" value="+ $i18n.getString('add_more_action')" onclick="addMoreAction();"></td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	<tbody>
+</table>
+<br>
+<table>
+	<tr>
+		<td colspan='3'>
+			<input type="submit" value="$i18n.getString( 'add' )" style="width:10em">
+			<input type="button" value="$i18n.getString( 'cancel' )" onclick="window.location.href='programRule.action?id=$program.id'" style="width:10em">
+		</td>
+	</tr>
+</table>
+
+<!-- Add Program Rule Variable -->
+
+<div id='programRuleVariableDiv' style="display:none;">
+	<table>
+		<tr>
+			<td>$i18n.getString('source_type')</td>
+			<td>
+				<select type="" id="sourceType" name="sourceType" onchange="sourceTypeOnChange()" style="width:250px;">
+					<option value="DATAELEMENT_NEWEST_EVENT_PROGRAM">$i18n.getString("data_element_newest_event_program")</option>
+					<option value="DATAELEMENT_NEWEST_EVENT_PROGRAM_STAGE">$i18n.getString("data_element_newest_event_program_stage")</option>
+				</select>
+			</td>
+		</td>
+		<tr>
+			<td>$i18n.getString('source_program_stage')</td>
+			<td>
+				<select type="" id="programStageId" disabled style="width:250px;" onchange="getDataElementsByStage();">
+					<option value="">[All]</option>
+					#foreach( $programStage in $program.programStages )
+						<option value="$programStage.uid">$programStage.displayName</option>
+					#end
+				</select>
+			</td>
+		</td>
+		<tr>
+			<td>$i18n.getString('source_dataElement') <em title="$i18n.getString( "required" )" class="required">*</em></td>
+			<td>
+				<select type="" id="dataElementId" style="width:250px;">
+					#foreach( $programStage in $program.programStages )
+						#foreach( $psDataElement in $programStage.programStageDataElements )
+							<option value="$psDataElement.dataElement.uid">$psDataElement.dataElement.displayName</option>
+						#end
+					#end
+				</select>
+				<span style="color:red;display:none;" id="dataElementIdError" ></span>
+			</td>
+		</td>
+		<tr>
+			<td>$i18n.getString('variable_name') <em title="$i18n.getString( "required" )" class="required">*</em></td>
+			<td><input type="text" id="variableName" name="variableName" style="width:247px;" onkeypress="return variableNameKeyPress(event)" />
+			<span style="color:red;display:none;" id="variableNameError" ></span></td>
+		</td>
+		
+		<tr>
+			<td></td>
+			<td>
+				<input type='button' onclick="javascript:addProgramRuleVariable();" style="width:100px;" value="$i18n.getString('add')" />
+				<input type='button' onclick="javascript:closeVariableForm();" value="$i18n.getString('cancel')" style="width:100px;" />
+			</td>
+		</tr>
+	</table>
+</div>
+
+</form>

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramStageSectionForm.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramStageSectionForm.vm	2015-03-31 10:54:00 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/addProgramStageSectionForm.vm	2015-04-11 13:18:25 +0000
@@ -30,7 +30,7 @@
 <input type="hidden" id="programStageId" name="programStageId" value="$programStage.id"/>
 <table>
 	<thead>
-		<tr><th colspan="2">$i18n.getString( "section_details" )</th></tr>
+		<tr><th colspan="2">$i18n.getString( "program_stage_details" )</th></tr>
 	</thead>
 	<tbody>
 		<tr>

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/javascript/program.js'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/javascript/program.js	2014-08-26 12:43:04 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/javascript/program.js	2015-04-11 13:18:25 +0000
@@ -292,3 +292,12 @@
     }
   }
 }
+
+//-----------------------------------------------------------------------------
+// Program Rule
+//-----------------------------------------------------------------------------
+
+function programRule( context )
+{
+	location.href = 'programRule.action?id=' + context.id;
+}

=== added file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/javascript/programRule.js'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/javascript/programRule.js	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/javascript/programRule.js	2015-04-11 13:18:25 +0000
@@ -0,0 +1,430 @@
+
+$(function() {
+  dhis2.contextmenu.makeContextMenu({
+    menuId: 'contextMenu',
+    menuItemActiveClass: 'contextMenuItemActive'
+  });
+});
+
+// -----------------------------------------------------------------------------
+// View details
+// -----------------------------------------------------------------------------
+
+function showUpdateProgramRuleForm( context ) {
+  location.href = 'showUpdateProgramRuleForm.action?id=' + context.id;
+}
+
+function showProgramRuleDetails( context ) {
+	jQuery.getJSON( 'getProgramRule.action', { id: context.id },
+		function ( json ) {
+			setInnerHTML( 'nameField', json.programRule.name );	
+			setInnerHTML( 'descriptionField', json.programRule.description );
+			showDetails();
+	});
+}
+
+
+// -----------------------------------------------------------------------------
+// Delete Program Rule
+// -----------------------------------------------------------------------------
+
+function removeProgramRule(context)
+{
+	var result = window.confirm( i18n_confirm_delete + "\n\n" + context.name );
+	if ( result )
+    {
+		$.ajax({
+			type: "DELETE"
+			,url:  "../api/programRules/" + context.uid
+			,success: function(){
+				
+				jQuery( "tr#tr" + context.id ).remove();
+				
+				jQuery( "table.listTable tbody tr" ).removeClass( "listRow listAlternateRow" );
+				jQuery( "table.listTable tbody tr:odd" ).addClass( "listAlternateRow" );
+				jQuery( "table.listTable tbody tr:even" ).addClass( "listRow" );
+				jQuery( "table.listTable tbody" ).trigger("update");
+
+				setHeaderDelayMessage( i18n_delete_success );
+    	    	
+			}
+			,error:  function(){}
+		});
+	
+	}
+}
+
+// -----------------------------------------------------------------------------
+// Program Rule Variables
+// --
+
+var program_DataElements = new Array();
+
+function removeDuplicateOptions()
+{
+	$("#sourceFieldList tr").each(function(){
+		var deName = $(this).find('td:first').html();
+		var deId = $(this).find('input').attr("deId");
+		program_DataElements[deId] = deName;
+	});
+	
+	$("#programRuleVariableDiv #dataElementId option").each(function () {
+		if(program_DataElements[this.value]) {
+			$(this).remove();
+		} else {
+			program_DataElements[this.value] = this.text;
+		}
+	});
+}
+
+function getDataElementsByStage()
+{
+	var programStageField = $("#programRuleVariableDiv #programStageId");
+	var programStageId = programStageField.val();
+	var dataElementField = $("#programRuleVariableDiv #dataElementId");
+	clearListById('programRuleVariableDiv #dataElementId');
+				
+	if( programStageId != "" )
+	{
+		$.ajax({
+			type: 'GET'
+			,url: "../api/programStages/" + programStageId + ".json?fields=programStageDataElements[dataElement[id,name]]"
+			,dataType: "json"
+			,success: function(json){
+				for( var i in json.programStageDataElements )
+				{
+					var dataElement = json.programStageDataElements[i].dataElement;
+					dataElementField.append("<option value='" + dataElement.id + "'>" + dataElement.name + "</option>");
+				}
+				removeAvailableVariables();
+			}
+		});
+	}
+	else
+	{
+		for( var i in program_DataElements )
+		{
+			dataElementField.append("<option value='" + i + "'>" + program_DataElements[i] + "</option>");
+		}
+		removeAvailableVariables();
+	}
+	
+	
+}
+
+function removeAvailableVariables()
+{
+	$("#sourceFieldList tr").find("input").each(function(){
+		var deId = $(this).attr('deId');
+		$("#programRuleVariableDiv #dataElementId option").each(function(){
+			if( deId == $(this).attr('value') )
+			{
+				$(this).remove();
+			}
+		});
+	});
+}
+
+function validateVariable( dataElementId, variableName )
+{
+	var valid = true;
+	hideById('variableNameError');
+	hideById('dataElementIdError');
+	
+	if( dataElementId == null || dataElementId == "" )
+	{
+		setInnerHTML('dataElementIdError', i18n_this_field_is_required);
+		showById('dataElementIdError');
+		return false;
+	} 
+	else if( variableName == "" )
+	{
+		setInnerHTML('variableNameError', i18n_this_field_is_required);
+		showById('variableNameError');
+		return false;
+	} 
+	
+	$("#sourceFieldList tr").find("td:last").each(function(){
+		if( variableName == $(this).find('input').attr('realValue') )
+		{
+			setInnerHTML('variableNameError', i18n_name_in_use);
+			showById('variableNameError');
+			valid = false;
+			return;
+		}
+	});
+	return valid;
+}
+
+function addProgramRuleVariable()
+{
+	var dataElementId = getFieldValue('programRuleVariableDiv #dataElementId');
+	var variableName = getFieldValue('variableName');
+	if( validateVariable( dataElementId, variableName ) )
+	{	
+		hideById('variableNameError');
+		
+		var sourceType = getFieldValue('sourceType');
+		var programStageId = getFieldValue('programStageId');
+		var dataElementName = $('#dataElementId option:selected').text();
+		var json_Data = getVariableJson( variableName, sourceType, dataElementId, programStageId );
+		
+		var clazz = "listAlternateRow";
+		if( $("#sourceFieldList tr").length % 2 == 0 )
+		{
+			clazz = "listRow";
+		}
+			
+		var row = "<tr class='" + clazz + " newVariable' jsonData='" + json_Data + "'><td>" + dataElementName + "</td><td>" + addVariableButton( variableName, dataElementId ) +"</td></tr>";
+		$("#sourceFieldList").append(row);
+		
+		// Remove the data element from Add the Source field form. This data was used, so cannot be used for any variables.
+		
+		$('#programRuleVariableDiv #dataElementId option[value="' + dataElementId + '"]').remove();		
+		$("#programRuleVariableDiv").dialog("close");
+	}
+	
+}
+
+function addVariableButton( name, deId )
+{
+	return "<input type='button' deId='" + deId + "' realValue='" + name + "' value='$" + name + "' style='width:150px;' onclick='insertVariable(this)'/>";
+}
+
+function insertVariable(_this)
+{
+	insertTextCommon('condition', _this.value + " "); 
+}
+
+function getVariableJson( variableName, sourceType, dataElementId, programStageId )
+{
+	var json_Data = '{ '
+		+ '"name": "' + variableName + '",'
+		+ '"sourceType": "' +  sourceType + '",'
+		+ '"dataElement": { "id" : "' + dataElementId + '"},'
+		+ '"program": { "id" :"' + getFieldValue("programId") + '"},'
+		+ '"programStage": { "id" :  "' + programStageId + '"}'
+	+ '}';
+	
+	return json_Data;
+}
+
+function closeVariableForm()
+{
+	$("#programRuleVariableDiv").dialog("close");
+}
+
+// --
+// Program Rule Variables
+// -----------------------------------------------------------------------------
+
+
+
+// -----------------------------------------------------------------------------
+// Add new - Program Rule
+// --
+
+// 0 : Program Rule List
+// 1 : Add new
+// 2 : Update 
+var status = 0; 
+function validateProgramRule()
+{
+	status = 1;
+	var valid = true;
+	$("#actionTB tr").find(".content").each(function(){
+		if( $(this).val() == "" )
+		{
+			$(this).css('background-color', 'pink');
+			$(this).attr('placeholder', 'i18n_please_enter_action_description');
+			unLockScreen();
+			valid = false;
+			return;
+		}
+	})
+	
+	if( valid ) {
+		addProgramRule();
+	}
+}
+
+function addProgramRule()
+{
+	lockScreen();
+	var json_Data = { 
+		"name": getFieldValue('name'),
+		"condition": getFieldValue('condition'),
+		"description": getFieldValue('description'),
+		"program":{ "id": getFieldValue('programId')}
+	};
+	
+	var programRuleId = getFieldValue('programRuleId')
+	var actionMethod = ( programRuleId === undefined ) ? "POST" : "PUT";
+	var url = ( programRuleId === undefined ) ? "../api/programRules/" : "../api/programRules/" + programRuleId;
+	
+	$.ajax({
+			type: actionMethod
+			,url: url
+			,dataType: "json"
+			,async: false
+			,contentType: "application/json"
+			,data: JSON.stringify(json_Data)
+			,success: function(data){
+				var programRuleId = data.lastImported;
+				saveProgramRuleVariable();
+				saveAction( programRuleId );
+			}
+			,error:  function(){}
+		});
+
+	return false;
+}
+
+
+function saveProgramRuleVariable()
+{
+	$("#sourceFieldList tr.newVariable").each(function(){
+		var json_Data = $(this).attr("jsonData");
+		
+		$.ajax({
+			type: "POST"
+			,url: "../api/programRuleVariables/"
+			,dataType: "json"
+			,async: false
+			,contentType: "application/json"
+			,data: json_Data
+			,success: function(){}
+			,error:  function(){}
+		});
+	});
+}
+
+function saveAction( programRuleId )
+{
+	$("#actionTB tr").each(function(){
+		var row = $(this);
+		var json_Data = { 
+			"programRuleActionType": row.find(".actionList").val(),
+			"programRule":{ "id":programRuleId },
+			"dataElement":{ "id": row.find(".actionDEs").val() },
+			"content": row.find(".content").val()
+		}
+		
+		var actionId = $(this).attr('id');		
+		var actionMethod = ( actionId === undefined ) ? "POST" : "PUT";
+		var url = ( actionId === undefined ) ? "../api/programRuleActions/" : "../api/programRuleActions/" + actionId;
+	
+		$.ajax({
+			type: actionMethod
+			,url: url
+			,dataType: "json"
+			,async: false
+			,contentType: "application/json"
+			,data: JSON.stringify(json_Data)
+			,success: function(){}
+			,error:  function(){}
+		});
+	});
+	
+}
+
+/* 
+
+$( document ).ajaxStop(function() {
+	if( status == 1 )
+	{
+		status = 0;
+		window.location.href='programRule.action?id=' + getFieldValue('programLocalId');
+	}
+}); 
+*/
+
+// --
+// Add new - Program Rule
+// -----------------------------------------------------------------------------
+
+
+function sourceTypeOnChange()
+{
+	var sourceType = getFieldValue("sourceType");
+	if( sourceType == "DATAELEMENT_NEWEST_EVENT_PROGRAM" ){
+		setFieldValue( "programStageId", "" );
+		disable("programStageId");
+	}
+	else{
+		enable("programStageId");
+	}
+}
+
+function addSourceFieldForm()
+{
+	hideById('variableNameError');
+	$("#programRuleVariableDiv").dialog({
+		title: i18n_add_source_field,
+		height: 230,
+		width:450,
+		modal: true,
+		zIndex:99999
+	});	
+}
+
+function addMoreAction()
+{
+	var table = $("#actionTB");
+	var dataElementSelector = "<select class='actionDEs' style='width:100%;' >";
+	for( var i in program_DataElements )
+	{
+		dataElementSelector += "<option value='" + i + "'>" + program_DataElements[i] + "</option>";
+	}
+	dataElementSelector += "</select>";
+	
+	var clazz = "class='listAlternateRow'";
+	if( $("#actionTB tr").length % 2 == 0 )
+	{
+		clazz = "class='listRow'";
+	}
+	var row = "<tr " + clazz + ">"
+			+ "<td><select class='actionList' style='width:100%'>"
+			+ "	<option value='DISPLAYTEXT'>" + i18n_display_text + "</option>"
+			+ "	<option value='DISPLAYKEYVALUEPAIR'>" + i18n_shows_a_key_data_box + "</option>"
+			+ "	<option value='HIDEFIELD'>" + i18n_hide_field + "</option>"
+			+ "	<option value='ASSIGNVARIABLE'>" + i18n_assign_variable + "</option>"
+			+ "	<option value='SHOWWARNING'>" + i18n_show_warning + "</option>"
+			+ "	<option value='SHOWERROR'>" + i18n_show_error + "</option>"
+			+ "</select>"
+			+ "</td>"
+			+ "<td><input type='text' class='content' style='width:97%;'/></td>"
+			+ "<td>" + dataElementSelector + "</td>"
+			+ "<td><input type='button' value='-' onclick='javascript:removeActionRow(this)';></td>"
+			+ "</tr>";
+	table.append(row);
+}
+
+function removeActionRow(_this)
+{
+	$(_this).closest('tr').remove();
+}
+
+function variableNameKeyPress(event)
+{
+	var key = event.keyCode || event.charCode || event.which;
+	
+	// Allow Numbers || A-Z || a-z
+	if( ( key>=48 && key<=57 ) ||  ( key>=65 && key<=90 ) ||  ( key>=97 && key<=122 ) )
+	{
+		return true;
+	}
+	return false;
+}
+
+function showUpdateAttributeForm(context)
+{
+	window.location.href='showUpdateProgramRuleForm.action?id=' + context.id
+}
+
+function clearRuleFilter( programId ) {
+	setFieldValue('key','');
+    jQuery.cookie( "currentPage", null );
+    jQuery.cookie( "currentKey", null );
+    window.location.href = 'programRule.action?id=' + programId;
+}

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programList.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programList.vm	2015-03-10 13:00:30 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programList.vm	2015-04-11 13:18:25 +0000
@@ -8,7 +8,8 @@
     <li data-enabled="canUpdate"><a data-target-fn="showProgramUserRoleForm"><i class="fa fa-plus"></i>&nbsp;&nbsp;$i18n.getString( "assign_program_to_userroles" )</a></li>
     <li data-enabled="canUpdate"><a data-target-fn="showUpdateProgramForm"><i class="fa fa-edit"></i>&nbsp;&nbsp;$i18n.getString( "edit" )</a></li>
     <li data-enabled="canUpdate"><a data-target-fn="programStageManagement"><i class="fa fa-edit"></i>&nbsp;&nbsp;$i18n.getString( "view_program_stages" )</a></li>
-    <li data-enabled="canManageTemplateMessage"><a data-target-fn="programReminder"><i class="fa fa-edit"></i>&nbsp;&nbsp;$i18n.getString( "view_template_reminder_message" )</a></li>
+    <li data-enabled="canManageTemplateMessage"><a data-target-fn="programReminder"><i class="fa fa-edit"></i>&nbsp;&nbsp;$i18n.getString( "view_template_reminder_message" )</a></li> 
+	<li data-enabled="canManageProgramRule"><a data-target-fn="programRule"><i class="fa fa-edit"></i>&nbsp;&nbsp;$i18n.getString( "view_program_rule" )</a></li>
     <li data-enabled="canUpdate"><a data-target-fn="validationCriteria"><i class="fa fa-edit"></i>&nbsp;&nbsp;$i18n.getString( "view_validation_criteria" )</a></li>
     <li data-enabled="canUpdate"><a data-target-fn="programValidationManagement"><i class="fa fa-edit"></i>&nbsp;&nbsp;$i18n.getString( "view_validation_rule" )</a></li>
     <li data-enabled="canUpdate"><a data-target-fn="programIndicatorManagementForm"><i class="fa fa-edit"></i>&nbsp;&nbsp;$i18n.getString( "view_program_indicator" )</a></li>
@@ -47,6 +48,7 @@
           data-can-manage="$security.canManage( $program )"
           data-can-update="$security.canUpdate( $program )"
           data-can-manage-template-message="#if($program.type!=3)true#{else}false#end"
+		  data-can-manage-program-rule="#if( $auth.hasAccess( "dhis-web-maintenance-program", "programRule" ) ) true #{else}false#end"
           data-can-delete="$security.canDelete( $program )"
           data-can-manage-form="#if( $auth.hasAccess( "dhis-web-maintenance-program", "programIndicator" ) && $program.type !='3' )true#{else}false#end">
           <td>$encoder.htmlEncode( $!program.displayName )</td>

=== added file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programRule.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programRule.vm	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programRule.vm	2015-04-11 13:18:25 +0000
@@ -0,0 +1,77 @@
+
+#sharingDialog()
+
+<h3>$i18n.getString( "program_rule_management" )</h3>
+
+<h4>$program.displayName</h4>
+
+<div id="contextMenu" class="contextMenu">
+  <ul id="contextMenuItems" class="contextMenuItems">
+    <li data-enabled="canUpdate"><a data-target-fn="showUpdateAttributeForm"><i class="fa fa-edit"></i>&nbsp;&nbsp;$i18n.getString( "edit" )</a></li>
+    <li data-enabled="canUpdate"><a data-target-fn="translateWithContext"><i class="fa fa-globe"></i>&nbsp;&nbsp;$i18n.getString( "translation_translate" )</a></li>
+    <li data-enabled="canDelete"><a data-target-fn="removeProgramRule"><i class="fa fa-trash-o"></i>&nbsp;&nbsp;$i18n.getString( "remove" )</a></li>
+    <li><a data-target-fn="showProgramRuleDetails"><i class="fa fa-info-circle"></i>&nbsp;&nbsp;$i18n.getString( "show_details" )</a></li>
+  </ul>
+</div>
+
+<table class="mainPageTable">
+  <tr>
+    <td style="vertical-align:top">
+		<table width="100%">
+			<tr valign="bottom">
+				<td>
+					<form id="filterKeyForm" action="programRule.action" method="GET" onsubmit="submitFilter()">
+						<input type="text" id="key" name="key" value="$!key" placeholder="Filter by name" class="filterInput">
+						<input type="hidden" id="curKey" name="curKey" value="">
+						<input type="submit" id="filterButton" value="Filter" class="filterButton">
+						<input type="button" value="Clear" onclick="javascript:clearRuleFilter($program.id)" class="filterButton">
+						<input type="hidden" id="id" name="id" value="$program.id" >
+					</form>
+				</td>
+				<td colspan="3" style="text-align:right">
+					<input type="button" value="$i18n.getString( 'add_new' )" onclick="window.location.href='showAddProgramRuleForm.action?id=$program.id'" style="width:100px;"><br>
+					<input type="button" value="$i18n.getString( 'back' )" onclick="window.location.href='program.action'" style="width:100px;">
+				</td>	
+			</tr>
+		</table>
+			
+		<table class="listTable">
+			<col>          
+			<thead>
+			  <tr>
+				<th>$i18n.getString( "name" )</th>
+				<th>$i18n.getString( "description" )</th>
+			  </tr>
+			</thead>
+			<tbody id="list">
+          #foreach( $programRule in $programRules )
+            <tr id="tr${programRule.id}" data-id="$!programRule.id" data-uid="$!programRule.uid" data-type="ProgramRule" data-name="$encoder.htmlEncode( $!programRule.displayName )"
+                data-can-manage="$security.canManage( $programRule )"
+                data-can-update="$security.canUpdate( $programRule )"
+                data-can-delete="$security.canDelete( $programRule )">
+                <td>$encoder.htmlEncode( $!programRule.displayName )</td>
+                <td>$encoder.htmlEncode( $!programRule.description )</td>
+            </tr>
+          #end
+		 
+      </tbody>
+      </table>
+		
+		</td>
+
+		<td id="detailsData">
+      <div id="detailsArea">
+        <div id="hideDetailsArea">
+          <a href="javascript:hideDetails()" title="$i18n.getString( 'hide_details' )"><img src="../images/hide.png" alt="$i18n.getString( 'hide_details' )"></a>
+			</div>
+				<p><label class="bold">$i18n.getString( "name" ):</label><br><span id="nameField"></span></p>
+				<p><label class="bold">$i18n.getString( "description" ):</label><br><span id="descriptionField"></span></p>
+			</div>
+
+		</td>
+  </tr>
+</table>
+
+<script type="text/javascript">
+	var i18n_confirm_delete = '$encoder.jsEscape( $i18n.getString( "confirm_delete_program_rule" ) , "'" )';
+</script>

=== added file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/updateProgramRule.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/updateProgramRule.vm	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/updateProgramRule.vm	2015-04-11 13:18:25 +0000
@@ -0,0 +1,224 @@
+<script>
+	
+	jQuery( document ).ready( function()
+	{	
+		validation2( 'programRuleForm', function( form )
+		{
+			validateProgramRule();
+		},{
+			'beforeValidateHandler' : function()
+			{
+				if( $("#actionTB tr").length == 0 )
+				{
+					setFieldValue('hasAction','');
+				}
+				else
+				{
+					setFieldValue('hasAction','yes');
+				}
+			},
+			'rules' : getValidationRules( "programRule" )
+		});
+		
+		checkValueIsExist( "name", "validateProgramRule.action",{programId:"$programRule.program.id", id:"$programRule.id"}  );
+		removeDuplicateOptions();
+	});
+	
+	var i18n_add_source_field = '$encoder.jsEscape( $i18n.getString( "add_source_field" ) , "'" )';
+	var i18n_display_text = '$encoder.jsEscape( $i18n.getString( "display_text" ) , "'" )';
+	var i18n_shows_a_key_data_box = '$encoder.jsEscape( $i18n.getString( "shows_a_key_data_box" ) , "'" )';
+	var i18n_hide_field = '$encoder.jsEscape( $i18n.getString( "hide_field" ) , "'" )';
+	var i18n_assign_variable = '$encoder.jsEscape( $i18n.getString( "assign_variable" ) , "'" )';
+	var i18n_show_warning = '$encoder.jsEscape( $i18n.getString( "show_warning" ) , "'" )';
+	var i18n_show_error = '$encoder.jsEscape( $i18n.getString( "show_error" ) , "'" )';
+	var i18n_this_field_is_required = '$encoder.jsEscape( $i18n.getString( "this_field_is_required" ) , "'")';
+	var i18n_name_in_use = '$encoder.jsEscape( $i18n.getString( "name_in_use" ) , "'")';
+	var i18n_please_enter_action_description = '$encoder.jsEscape( $i18n.getString( "please_enter_action_description" ) , "'")';
+	var i18n_confirm_delete = '$encoder.jsEscape( $i18n.getString( "confirm_delete_program_rule" ) , "'")';
+</script>
+
+<h3>$i18n.getString( "create_new_program_rule" )</h3>
+									
+<form id="programRuleForm" name="programRuleForm" action="updateProgramRule.action" method="post" class="inputForm">
+
+<input type='hidden' id='programId' name='programId' value="$programRule.program.uid" />
+<input type='hidden' id='programLocalId' name='programLocalId' value="$programRule.program.id" />
+<input type='hidden' id='programRuleId' name='programRuleId' value="$programRule.uid" />
+
+<table width="70%">
+	<col width="10%">
+	<col width="40%">
+	<col width="25%">
+	<col width="25%">
+	<thead>
+      <tr>
+        <th colspan="4">$i18n.getString( "program_rule_details" )</th>
+      </tr>
+    </thead>
+    
+	<tbody>
+		<tr>
+			<td><label for="name">$i18n.getString( "name" ) <em title="$i18n.getString( "required" )" class="required">*</em></label></td>
+			<td colspan='3'><input type="text" id="name" name="name" style="width:98%" value='$programRule.name' ></td>
+		</tr>	
+		
+		<tr>
+			<td><label for="description">$i18n.getString( "description" ) <em title="$i18n.getString( "required" )" class="required">*</em></label></td>
+			<td colspan='3'><input type="text" id="description" name="description" style="width:98%" value='$programRule.description' /></td>
+		</tr>
+		
+		<tr>
+			<th colspan="2">1. $i18n.getString("source_fields")</th>
+			<th colspan="2">2. $i18n.getString("expression_evaluate_the_source_fields") <em title="$i18n.getString( "required" )" class="required">*</em></th>
+		</tr>
+		<tr>
+			<td colspan='2'>
+				<fieldset style="height:100%;">
+					<div style="height:80px;border:1px solid black; overflow: auto;">
+						<table id='sourceFieldList' style="height:80px;width:100%" >
+							<col width="50%" />
+							<col width="50%" />
+							#set($idx = 0 )
+							#foreach($ruleVariable in $ruleVariables)
+								#set( $json_Data='{"name":"' + $ruleVariable.name + '"'
+									+ ',"sourceType":"' + $ruleVariable.sourceType + '"'
+									+ ',"dataElement":{ "id":"' + $ruleVariable.dataElement.id + '"}'
+									+ ',"program":{"id":"' + $ruleVariable.program.id + '"}'
+									+ ',"programStage":{"id":"' + "$!ruleVariable.programStage.id" + '"}}' )
+								#set($clazz = "listAlternateRow")
+								#if( $idx % 2 == 0 )
+									#set($clazz = "listRow")
+								#end		
+								#set($idx = $idx + 1 )
+								<tr class="$clazz" jsonData='$json_Data' id="$ruleVariable.uid">
+									<td>$encoder.htmlEncode($ruleVariable.dataElement.displayName)</td>
+									<td><input type='button' deId='$ruleVariable.dataElement.uid' realValue='$ruleVariable.name' value='$$ruleVariable.name' style='width:150px;' onclick='insertVariable(this)'/></td>
+								</tr>
+							#end
+						</table>
+					</div><br>
+					<input type="button" id="addMoreVariableBtn" value="+ $i18n.getString('add_source_field')" onclick="javascript:addSourceFieldForm();"/>
+				</fieldset>
+			</td>			
+			<td colspan='2'>
+				<fieldset>
+					<textarea size="10" id='condition' name='condition' style="width:98%;border:none">$programRule.condition</textarea>
+				</fieldset>
+			</td>
+		</tr>
+		
+		<tr>
+			<th colspan="3">3. $i18n.getString("actions_that_is_executed_when_expression_is_true") <em title="$i18n.getString( "required" )" class="required">*</em>
+			</th>
+			<td>
+				<input type="hidden" id="hasAction" name="hasAction" class="{validate:{required:true}}" >
+			</td>
+		</tr>
+		<tr>
+			<td colspan="4">
+				<table width="100%">
+					<col width="20%">
+					<col width="60%">
+					<col width="20%">
+					<tbody id='actionTB'>
+						#set($idx = 0 )
+						#foreach( $action in $programRule.programRuleActions )
+						
+							#set($clazz = "class='listAlternateRow'")
+							#if( $idx % 2 == 0 )
+								#set($clazz = "class='listRow'")
+							#end		
+							#set($idx = $idx + 1 )
+							
+							<tr $clazz id="$action.uid">								
+								<td>
+									<select class='actionList' style='width:100%'>
+										<option value='DISPLAYTEXT' #if($action.programRuleActionType=='DISPLAYTEXT') selected #end>$i18n.getString("display_text")</option>
+										<option value='DISPLAYKEYVALUEPAIR' #if($action.programRuleActionType=='DISPLAYKEYVALUEPAIR') selected #end>$i18n.getString("shows_a_key_data_box")</option>
+										<option value='HIDEFIELD' #if($action.programRuleActionType=='HIDEFIELD') selected #end>$i18n.getString("hide_field")</option>
+										<option value='ASSIGNVARIABLE' #if($action.programRuleActionType=='ASSIGNVARIABLE') selected #end>$i18n.getString("assign_variable")</option>
+										<option value='SHOWWARNING' #if($action.programRuleActionType=='SHOWWARNING') selected #end>$i18n.getString("show_warning")</option>
+										<option value='SHOWERROR' #if($action.programRuleActionType=='SHOWERROR') selected #end>$i18n.getString("show_error")</option>
+									</select>
+								</td>
+								<td><input type='text' class='content' style='width:97%;' value='$encoder.htmlEncode($action.content)'/></td>
+								<td>
+									<select class='actionDEs' style='width:100%;'>
+										<option value="$programRule.dataElement.uid">$encoder.htmlEncode($action.dataElement.displayName)</option>
+									</select>
+								</td>
+								<td><input type='button' value='-' onclick='javascript:removeActionRow(this)';></td>
+							</tr>
+						#end
+						</tbody>
+						<td><input type="button" value="+ $i18n.getString('add_more_action')" onclick="addMoreAction();"></td>
+					</tr>
+				</table>
+			</td>
+		</tr>
+	<tbody>
+</table>
+<br>
+<table>
+	<tr>
+		<td colspan='3'>
+			<input type="submit" value="$i18n.getString( 'update' )" style="width:10em">
+			<input type="button" value="$i18n.getString( 'cancel' )" onclick="window.location.href='programRule.action?id=$programRule.program.id'" style="width:10em">
+		</td>
+	</tr>
+</table>
+
+<!-- Add Program Rule Variable -->
+
+<div id='programRuleVariableDiv' style="display:none;">
+	<table>
+		<tr>
+			<td>$i18n.getString('source_type')</td>
+			<td>
+				<select type="" id="sourceType" name="sourceType" onchange="sourceTypeOnChange()" style="width:250px;">
+					<option value="DATAELEMENT_NEWEST_EVENT_PROGRAM">$i18n.getString("data_element_newest_event_program")</option>
+					<option value="DATAELEMENT_NEWEST_EVENT_PROGRAM_STAGE">$i18n.getString("data_element_newest_event_program_stage")</option>
+				</select>
+			</td>
+		</td>
+		<tr>
+			<td>$i18n.getString('source_program_stage')</td>
+			<td>
+				<select type="" id="programStageId" disabled style="width:250px;" onchange="getDataElementsByStage();">
+					<option value="">[All]</option>
+					#foreach( $programStage in $program.programStages )
+						<option value="$programStage.uid">$programStage.displayName</option>
+					#end
+				</select>
+			</td>
+		</td>
+		<tr>
+			<td>$i18n.getString('source_dataElement') <em title="$i18n.getString( "required" )" class="required">*</em></td>
+			<td>
+				<select type="" id="dataElementId" style="width:250px;">
+					#foreach( $programStage in $programRule.program.programStages )
+						#foreach( $psDataElement in $programStage.programStageDataElements )
+							<option value="$psDataElement.dataElement.uid">$psDataElement.dataElement.displayName</option>
+						#end
+					#end
+				</select>
+				<span style="color:red;display:none;" id="dataElementIdError" ></span>
+			</td>
+		</td>
+		<tr>
+			<td>$i18n.getString('variable_name') <em title="$i18n.getString( "required" )" class="required">*</em></td>
+			<td><input type="text" id="variableName" name="variableName" style="width:247px;" onkeypress="return variableNameKeyPress(event)" />
+			<span style="color:red;display:none;" id="variableNameError" ></span></td>
+		</td>
+		
+		<tr>
+			<td></td>
+			<td>
+				<input type='button' onclick="javascript:addProgramRuleVariable();" style="width:100px;" value="$i18n.getString('add')" />
+				<input type='button' onclick="javascript:closeVariableForm();" value="$i18n.getString('cancel')" style="width:100px;" />
+			</td>
+		</tr>
+	</table>
+</div>
+
+</form>

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/updateProgramStageSectionForm.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/updateProgramStageSectionForm.vm	2015-03-31 10:54:00 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/updateProgramStageSectionForm.vm	2015-04-11 13:18:25 +0000
@@ -31,7 +31,7 @@
 
 <table>
 	<thead>
-		<tr><th colspan="2">$i18n.getString( "section_details" )</th></tr>
+		<tr><th colspan="2">$i18n.getString( "program_stage_details" )</th></tr>
 	</thead>
 	<tbody>
 		<tr>

=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/resources/org/hisp/dhis/user/i18n_module.properties'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/resources/org/hisp/dhis/user/i18n_module.properties	2015-03-18 18:51:30 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-user/src/main/resources/org/hisp/dhis/user/i18n_module.properties	2015-04-11 13:18:25 +0000
@@ -282,6 +282,9 @@
 F_OPTIONSET_ADD=Add Option Set
 F_INSERT_CUSTOM_JS_CSS=Insert custom Java script and CSS
 F_VIEW_UNAPPROVED_DATA=View unapproved data
+F_PROGRAM_RULE_MANAGEMENT = Manage Program Rule
+F_PROGRAM_RULE_ADD = Add Program Rule
+F_PROGRAM_RULE_UPDATE = Update Program Rule
 
 #-- FRED API module -----------------------------------------------------------#