← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 19941: Analysis, relative period date param implemented.

 

------------------------------------------------------------
revno: 19941
committer: Jan Henrik Overland <janhenrik.overland@xxxxxxxxx>
branch nick: dhis2
timestamp: Wed 2015-09-02 20:25:31 +0200
message:
  Analysis, relative period date param implemented.
modified:
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/scripts/core.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/scripts/eventreport.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/core.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/eventchart.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/core.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/map.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/core.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/table.js
  dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/core.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/eventchart.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/eventreport.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/map.js
  dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/table.js
  dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/eventchart.js
  dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/eventreport.js
  dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/map.js
  dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/table.js


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/scripts/core.js	2015-08-10 07:42:21 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/scripts/core.js	2015-09-02 18:25:31 +0000
@@ -557,6 +557,11 @@
 					//layout.sortOrder = Ext.isNumber(config.sortOrder) ? config.sortOrder : 0;
 					//layout.topLimit = Ext.isNumber(config.topLimit) ? config.topLimit : 0;
 
+                    // relative period date
+                    if (support.prototype.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
+
 					if (!validateSpecialCases()) {
 						return;
 					}
@@ -933,6 +938,26 @@
 				return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, conf.report.digitGroupSeparator[separator]);
 			};
 
+                // date
+            support.prototype.date = {};
+
+            support.prototype.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
 			// color
 			support.color = {};
 
@@ -2480,6 +2505,11 @@
                 if (view.collapseDataDimensions) {
                     paramString += '&collapseDataDimensions=true';
                 }
+                
+                // relative period date
+                if (view.relativePeriodDate) {
+                    paramString += '&relativePeriodDate=' + view.relativePeriodDate;
+                }
 
                 return paramString;
             };

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/scripts/eventreport.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/scripts/eventreport.js	2015-05-13 16:59:59 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-reports/scripts/eventreport.js	2015-09-02 18:25:31 +0000
@@ -167,33 +167,7 @@
 					{id: 'FinancialJuly', name: ER.i18n.financial_july},
 					{id: 'FinancialApril', name: ER.i18n.financial_april}
 				],
-                relativePeriods: [
-                    'THIS_WEEK',
-                    'LAST_WEEK',
-                    'LAST_4_WEEKS',
-                    'LAST_12_WEEKS',
-                    'LAST_52_WEEKS',
-                    'THIS_MONTH',
-                    'LAST_MONTH',
-                    'LAST_3_MONTHS',
-                    'LAST_6_MONTHS',
-                    'LAST_12_MONTHS',
-                    'THIS_BIMONTH',
-                    'LAST_BIMONTH',
-                    'LAST_6_BIMONTHS',
-                    'THIS_QUARTER',
-                    'LAST_QUARTER',
-                    'LAST_4_QUARTERS',
-                    'THIS_SIX_MONTH',
-                    'LAST_SIX_MONTH',
-                    'LAST_2_SIXMONTHS',
-                    'THIS_FINANCIAL_YEAR',
-                    'LAST_FINANCIAL_YEAR',
-                    'LAST_5_FINANCIAL_YEARS',
-                    'THIS_YEAR',
-                    'LAST_YEAR',
-                    'LAST_5_YEARS'
-                ]
+                relativePeriods: []
 			};
 
                 // aggregation type
@@ -222,7 +196,7 @@
                 west_fill_accordion_indicator: 56,
                 west_fill_accordion_dataelement: 59,
                 west_fill_accordion_dataset: 31,
-                west_fill_accordion_period: 330,
+                west_fill_accordion_period: 335,
                 west_fill_accordion_organisationunit: 58,
                 west_maxheight_accordion_indicator: 450,
                 west_maxheight_accordion_dataset: 350,
@@ -401,7 +375,7 @@
 
                 // collapseDataDimensions: boolean (false)
 
-                // outputType: string ('EVENT') - 'EVENT', 'TRACKED_ENTITY_INSTANCE', 'ENROLLMENT'
+                // outputType: string ('EVENT') - 'EVENT', 'TRACKED_ENTITY_IERTANCE', 'ENROLLMENT'
 
                 // aggregationType: string ('default') - 'default', 'count', 'sum'
 
@@ -614,6 +588,11 @@
 					//layout.sortOrder = Ext.isNumber(config.sortOrder) ? config.sortOrder : 0;
 					//layout.topLimit = Ext.isNumber(config.topLimit) ? config.topLimit : 0;
 
+                    // relative period date
+                    if (support.prototype.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
+
 					if (!validateSpecialCases()) {
 						return;
 					}
@@ -680,7 +659,7 @@
 
 					if (!(Ext.isArray(config.rows) && config.rows.length > 0)) {
 						//alert('No values found');
-						//return;
+						//return; // for ER, not for PT
 					}
 
 					if (config.rows.length > 0 && config.headers.length !== config.rows[0].length) {
@@ -990,6 +969,26 @@
 				return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, conf.report.digitGroupSeparator[separator]);
 			};
 
+                // date
+            support.prototype.date = {};
+
+            support.prototype.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
 			// color
 			support.color = {};
 
@@ -1968,8 +1967,8 @@
                     names,
 					headers,
                     booleanNameMap = {
-                        'true': ER.i18n.yes || 'Yes',
-                        'false': ER.i18n.no || 'No'
+                        '1': ER.i18n.yes || 'Yes',
+                        '0': ER.i18n.no || 'No'
                     };
 
 				response = Ext.clone(response);
@@ -2026,6 +2025,60 @@
                             support.prototype.array.sort(objects, 'ASC', 'sortingId');
                             header.ids = Ext.Array.pluck(objects, 'id');
                         }
+                        else if (header.type === 'java.lang.Boolean') {
+							var objects = [];
+
+                            for (var k = 0, id, fullId, name, isHierarchy; k < response.rows.length; k++) {
+                                id = response.rows[k][i] || emptyId;
+
+                                // hide NA data
+                                if (xLayout.hideNaData && id === emptyId) {
+                                    continue;
+                                }
+
+                                fullId = header.name + id;
+                                isHierarchy = service.layout.isHierarchy(xLayout, response, id);
+
+                                // add dimension name prefix if not pe/ou
+                                name = isMeta ? '' : header.column + ' ';
+
+                                // add hierarchy if ou and showHierarchy
+                                name = isHierarchy ? service.layout.getHierarchyName(ouHierarchy, names, id) : (names[id] || id);
+
+                                names[fullId] = name;
+
+                                // update rows
+                                response.rows[k][i] = fullId;
+
+                                // update ou hierarchy
+                                if (isHierarchy) {
+									ouHierarchy[fullId] = ouHierarchy[id];
+								}
+
+                                // update boolean metadata
+                                response.metaData.booleanNames[id] = booleanNameMap[id];
+                                response.metaData.booleanNames[fullId] = booleanNameMap[id];
+
+								objects.push({
+									id: fullId,
+									sortingId: id
+								});
+                            }
+
+                            // sort
+                            objects.sort(function(a, b) {
+                                if (a.sortingId === emptyId) {
+                                    return 1;
+                                }
+                                else if (b.sortingId === emptyId) {
+                                    return -1;
+                                }
+
+                                return a.sortingId - b.sortingId;
+                            });
+
+                            header.ids = Ext.Array.pluck(objects, 'id');
+                        }
                         else if (header.name === 'pe') {
                             var selectedItems = xLayout.dimensionNameIdsMap['pe'],
                                 isRelative = false;
@@ -2073,15 +2126,9 @@
 									ouHierarchy[fullId] = ouHierarchy[id];
 								}
 
-                                // update boolean metadata
-                                if (header.type === 'java.lang.Boolean') {
-                                    response.metaData.booleanNames[id] = booleanNameMap[id];
-                                    response.metaData.booleanNames[fullId] = booleanNameMap[id];
-                                }
-
 								objects.push({
 									id: fullId,
-									sortingId: header.name === 'pe' ? fullId : name
+									sortingId: name
 								});
                             }
 
@@ -2262,26 +2309,37 @@
 			};
 
 			web.window.addHideOnBlurHandler = function(w) {
-				var el = Ext.get(Ext.query('.x-mask')[0]);
-
-				el.on('click', function() {
-					if (w.hideOnBlur) {
-						w.hide();
-					}
-				});
+				var masks = Ext.query('.x-mask');
+
+                for (var i = 0, el; i < masks.length; i++) {
+                    el = Ext.get(masks[i]);
+
+                    if (el.getWidth() == Ext.getBody().getWidth()) {
+                        el.on('click', function() {
+                            if (w.hideOnBlur) {
+                                w.hide();
+                            }
+                        });
+                    }
+                }
 
 				w.hasHideOnBlurHandler = true;
 			};
 
 			web.window.addDestroyOnBlurHandler = function(w) {
-				var maskElements = Ext.query('.x-mask'),
-                    el = Ext.get(maskElements[0]);
-
-				el.on('click', function() {
-					if (w.destroyOnBlur) {
-						w.destroy();
-					}
-				});
+				var masks = Ext.query('.x-mask');
+
+                for (var i = 0, el; i < masks.length; i++) {
+                    el = Ext.get(masks[i]);
+
+                    if (el.getWidth() == Ext.getBody().getWidth()) {
+                        el.on('click', function() {
+                            if (w.destroyOnBlur) {
+                                w.destroy();
+                            }
+                        });
+                    }
+                }
 
 				w.hasDestroyOnBlurHandler = true;
 			};
@@ -2289,24 +2347,42 @@
 			// message
 			web.message = {};
 
-			web.message.alert = function(msg, type) {
+			web.message.alert = function(obj) {
                 var config = {},
+                    type,
                     window;
 
-                if (!msg) {
+                if (!obj || (Ext.isObject(obj) && !obj.message && !obj.responseText)) {
                     return;
                 }
 
-                type = type || 'error';
-
-				config.title = type === 'error' ? ER.i18n.error : (type === 'warning' ? ER.i18n.warning : ER.i18n.info);
+                // if response object
+                if (Ext.isObject(obj) && obj.responseText && !obj.message) {
+                    obj = Ext.decode(obj.responseText);
+                }
+
+                // if string
+                if (Ext.isString(obj)) {
+                    obj = {
+                        status: 'ERROR',
+                        message: obj
+                    };
+                }
+
+                // web message
+                type = (obj.status || 'INFO').toLowerCase();
+
+				config.title = obj.status;
 				config.iconCls = 'ns-window-title-messagebox ' + type;
 
                 // html
-                config.html = msg + (msg.substr(msg.length - 1) === '.' ? '' : '.');
+                config.html = '';
+                config.html += obj.httpStatusCode ? 'Code: ' + obj.httpStatusCode + '<br>' : '';
+                config.html += obj.httpStatus ? 'Status: ' + obj.httpStatus + '<br><br>' : '';
+                config.html += obj.message + (obj.message.substr(obj.message.length - 1) === '.' ? '' : '.');
 
                 // bodyStyle
-                config.bodyStyle = 'padding: 10px; background: #fff; max-width: 350px; max-height: ' + ns.app.centerRegion.getHeight() / 2 + 'px';
+                config.bodyStyle = 'padding: 12px; background: #fff; max-width: 600px; max-height: ' + ns.app.centerRegion.getHeight() / 2 + 'px';
 
                 // destroy handler
                 config.modal = true;
@@ -2460,6 +2536,11 @@
                 if (view.collapseDataDimensions) {
                     paramString += '&collapseDataDimensions=true';
                 }
+                
+                // relative period date
+                if (view.relativePeriodDate) {
+                    paramString += '&relativePeriodDate=' + view.relativePeriodDate;
+                }
 
                 return paramString;
             };
@@ -2477,7 +2558,10 @@
 
                 msg += '\n\n' + 'Hint: A good way to reduce the number of items is to use relative periods and level/group organisation unit selection modes.';
 
-                ns.alert(msg, 'warning');
+                ns.alert({
+                    status: 'INFO',
+                    message: msg
+                });
 			};
 
 			// report
@@ -3381,6 +3465,10 @@
 					rows = xResponse.rows,
                     names = xResponse.metaData.names,
                     optionNames = xResponse.metaData.optionNames,
+                    booleanNames = {
+                        '1': ER.i18n.yes,
+                        '0': ER.i18n.no
+                    },
                     pager = xResponse.metaData.pager,
                     count = pager.page * pager.pageSize - pager.pageSize
 					cls = 'pivot',
@@ -3418,8 +3506,7 @@
 					for (var j = 0, str, header, name; j < dimensionHeaders.length; j++) {
 						header = dimensionHeaders[j];
 						str = row[header.index];
-                        //str = names.hasOwnProperty(str) ? names[str] : str;
-                        str = optionNames[header.name + str] || optionNames[str] || names[str] || str;
+                        str = optionNames[header.name + str] || optionNames[str] || booleanNames[str] || names[str] || str;
 						name = web.report.query.format(str);
 
 						//if (header.name === 'ouname' && layout.showHierarchy) {

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/core.js	2015-08-10 07:42:21 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/core.js	2015-09-02 18:25:31 +0000
@@ -1135,6 +1135,11 @@
 					//layout.sortOrder = Ext.isNumber(config.sortOrder) ? config.sortOrder : 0;
 					//layout.topLimit = Ext.isNumber(config.topLimit) ? config.topLimit : 0;
 
+                    // relative period date
+                    if (support.prototype.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
+                    
                     // style
                     if (Ext.isObject(config.domainAxisStyle)) {
                         layout.domainAxisStyle = config.domainAxisStyle;
@@ -1571,6 +1576,26 @@
 				return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, conf.report.digitGroupSeparator[separator]);
 			};
 
+                // date
+            support.prototype.date = {};
+
+            support.prototype.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
 			// color
 			support.color = {};
 
@@ -3031,6 +3056,11 @@
                     paramString += '&collapseDataDimensions=true';
                 }
 
+                // relative period date
+                if (layout.relativePeriodDate) {
+                    paramString += '&relativePeriodDate=' + layout.relativePeriodDate;
+                }
+
                 return paramString;
             };
 

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/eventchart.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/eventchart.js	2015-05-13 16:59:59 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-event-visualizer/scripts/eventchart.js	2015-09-02 18:25:31 +0000
@@ -717,33 +717,7 @@
 					{id: 'FinancialJuly', name: EV.i18n.financial_july},
 					{id: 'FinancialApril', name: EV.i18n.financial_april}
 				],
-                relativePeriods: [
-                    'THIS_WEEK',
-                    'LAST_WEEK',
-                    'LAST_4_WEEKS',
-                    'LAST_12_WEEKS',
-                    'LAST_52_WEEKS',
-                    'THIS_MONTH',
-                    'LAST_MONTH',
-                    'LAST_3_MONTHS',
-                    'LAST_6_MONTHS',
-                    'LAST_12_MONTHS',
-                    'THIS_BIMONTH',
-                    'LAST_BIMONTH',
-                    'LAST_6_BIMONTHS',
-                    'THIS_QUARTER',
-                    'LAST_QUARTER',
-                    'LAST_4_QUARTERS',
-                    'THIS_SIX_MONTH',
-                    'LAST_SIX_MONTH',
-                    'LAST_2_SIXMONTHS',
-                    'THIS_FINANCIAL_YEAR',
-                    'LAST_FINANCIAL_YEAR',
-                    'LAST_5_FINANCIAL_YEARS',
-                    'THIS_YEAR',
-                    'LAST_YEAR',
-                    'LAST_5_YEARS'
-                ]
+                relativePeriods: []
 			};
 
                 // aggregation type
@@ -772,7 +746,7 @@
                 west_fill_accordion_indicator: 56,
                 west_fill_accordion_dataelement: 59,
                 west_fill_accordion_dataset: 31,
-                west_fill_accordion_period: 330,
+                west_fill_accordion_period: 335,
                 west_fill_accordion_organisationunit: 58,
                 west_maxheight_accordion_indicator: 450,
                 west_maxheight_accordion_dataset: 350,
@@ -954,7 +928,7 @@
 
                 // sortOrder: number
 
-                // outputType: string ('EVENT') - 'EVENT', 'TRACKED_ENTITY_INSTANCE', 'ENROLLMENT'
+                // outputType: string ('EVENT') - 'EVENT', 'TRACKED_ENTITY_IEVTANCE', 'ENROLLMENT'
 
                 // rangeAxisMaxValue: number
 
@@ -1118,7 +1092,7 @@
 
                     // period
                     if (!Ext.Array.contains(objectNames, 'pe') && !(config.startDate && config.endDate)) {
-                        ns.alert('At least one fixed period, one relative period or start/end dates must be specified.');
+                        ns.alert('At least one fixed period, one relative period or start/end dates must be specified');
                         return;
                     }
 
@@ -1128,7 +1102,7 @@
 
 					// column
 					if (!config.columns) {
-						ns.alert('No series items selected.');
+						ns.alert('No series items selected');
 						return;
 					}
 
@@ -1140,7 +1114,7 @@
 
 					// row
 					if (!config.rows) {
-						ns.alert('No category items selected.');
+						ns.alert('No category items selected');
 						return;
 					}
 
@@ -1218,6 +1192,11 @@
 					//layout.sortOrder = Ext.isNumber(config.sortOrder) ? config.sortOrder : 0;
 					//layout.topLimit = Ext.isNumber(config.topLimit) ? config.topLimit : 0;
 
+                    // relative period date
+                    if (support.prototype.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
+                    
                     // style
                     if (Ext.isObject(config.domainAxisStyle)) {
                         layout.domainAxisStyle = config.domainAxisStyle;
@@ -1654,6 +1633,26 @@
 				return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, conf.report.digitGroupSeparator[separator]);
 			};
 
+                // date
+            support.prototype.date = {};
+
+            support.prototype.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
 			// color
 			support.color = {};
 
@@ -2637,8 +2636,8 @@
                     names,
 					headers,
                     booleanNameMap = {
-                        'true': EV.i18n.yes || 'Yes',
-                        'false': EV.i18n.no || 'No'
+                        '1': EV.i18n.yes || 'Yes',
+                        '0': EV.i18n.no || 'No'
                     };
 
 				response = Ext.clone(response);
@@ -2695,6 +2694,60 @@
                             support.prototype.array.sort(objects, 'ASC', 'sortingId');
                             header.ids = Ext.Array.pluck(objects, 'id');
                         }
+                        else if (header.type === 'java.lang.Boolean') {
+							var objects = [];
+
+                            for (var k = 0, id, fullId, name, isHierarchy; k < response.rows.length; k++) {
+                                id = response.rows[k][i] || emptyId;
+
+                                // hide NA data
+                                if (xLayout.hideNaData && id === emptyId) {
+                                    continue;
+                                }
+
+                                fullId = header.name + id;
+                                isHierarchy = service.layout.isHierarchy(xLayout, response, id);
+
+                                // add dimension name prefix if not pe/ou
+                                name = isMeta ? '' : header.column + ' ';
+
+                                // add hierarchy if ou and showHierarchy
+                                name = isHierarchy ? service.layout.getHierarchyName(ouHierarchy, names, id) : (names[id] || id);
+
+                                names[fullId] = name;
+
+                                // update rows
+                                response.rows[k][i] = fullId;
+
+                                // update ou hierarchy
+                                if (isHierarchy) {
+									ouHierarchy[fullId] = ouHierarchy[id];
+								}
+
+                                // update boolean metadata
+                                response.metaData.booleanNames[id] = booleanNameMap[id];
+                                response.metaData.booleanNames[fullId] = booleanNameMap[id];
+
+								objects.push({
+									id: fullId,
+									sortingId: id
+								});
+                            }
+
+                            // sort
+                            objects.sort(function(a, b) {
+                                if (a.sortingId === emptyId) {
+                                    return 1;
+                                }
+                                else if (b.sortingId === emptyId) {
+                                    return -1;
+                                }
+
+                                return a.sortingId - b.sortingId;
+                            });
+
+                            header.ids = Ext.Array.pluck(objects, 'id');
+                        }
                         else if (header.name === 'pe') {
                             var selectedItems = xLayout.dimensionNameIdsMap['pe'],
                                 isRelative = false;
@@ -2742,15 +2795,9 @@
 									ouHierarchy[fullId] = ouHierarchy[id];
 								}
 
-                                // update boolean metadata
-                                if (header.type === 'java.lang.Boolean') {
-                                    response.metaData.booleanNames[id] = booleanNameMap[id];
-                                    response.metaData.booleanNames[fullId] = booleanNameMap[id];
-                                }
-
 								objects.push({
 									id: fullId,
-									sortingId: header.name === 'pe' ? fullId : name
+									sortingId: name
 								});
                             }
 
@@ -2900,24 +2947,42 @@
 			// message
 			web.message = web.message || {};
 
-			web.message.alert = function(msg, type) {
+			web.message.alert = function(obj) {
                 var config = {},
+                    type,
                     window;
 
-                if (!msg) {
+                if (!obj || (Ext.isObject(obj) && !obj.message && !obj.responseText)) {
                     return;
                 }
 
-                type = type || 'error';
-
-				config.title = type === 'error' ? EV.i18n.error : (type === 'warning' ? EV.i18n.warning : EV.i18n.info);
+                // if response object
+                if (Ext.isObject(obj) && obj.responseText && !obj.message) {
+                    obj = Ext.decode(obj.responseText);
+                }
+
+                // if string
+                if (Ext.isString(obj)) {
+                    obj = {
+                        status: 'ERROR',
+                        message: obj
+                    };
+                }
+
+                // web message
+                type = (obj.status || 'INFO').toLowerCase();
+
+				config.title = obj.status;
 				config.iconCls = 'ns-window-title-messagebox ' + type;
 
                 // html
-                config.html = msg + (msg.substr(msg.length - 1) === '.' ? '' : '.');
+                config.html = '';
+                config.html += obj.httpStatusCode ? 'Code: ' + obj.httpStatusCode + '<br>' : '';
+                config.html += obj.httpStatus ? 'Status: ' + obj.httpStatus + '<br><br>' : '';
+                config.html += obj.message + (obj.message.substr(obj.message.length - 1) === '.' ? '' : '.');
 
                 // bodyStyle
-                config.bodyStyle = 'padding: 10px; background: #fff; max-width: 350px; max-height: ' + ns.app.centerRegion.getHeight() / 2 + 'px';
+                config.bodyStyle = 'padding: 12px; background: #fff; max-width: 600px; max-height: ' + ns.app.centerRegion.getHeight() / 2 + 'px';
 
                 // destroy handler
                 config.modal = true;
@@ -3048,6 +3113,11 @@
                     paramString += '&collapseDataDimensions=true';
                 }
 
+                // relative period date
+                if (layout.relativePeriodDate) {
+                    paramString += '&relativePeriodDate=' + layout.relativePeriodDate;
+                }
+
                 return paramString;
             };
 
@@ -3064,7 +3134,10 @@
 
                 msg += '\n\n' + 'Hint: A good way to reduce the number of items is to use relative periods and level/group organisation unit selection modes.';
 
-                ns.alert(msg, 'warning');
+                ns.alert({
+                    status: 'INFO',
+                    message: msg
+                });
 			};
 
 			// report
@@ -4599,7 +4672,7 @@
                             labelFont: labelFont
                         }
                     });
-
+                    
                     return chart;
                 };
 
@@ -4646,6 +4719,8 @@
 		ns.core.support = support;
 		ns.core.service = service;
 		ns.core.web = web;
+
+		return ns;
 	};
 
 	// PLUGIN

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/core.js	2015-08-24 16:07:14 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/core.js	2015-09-02 18:25:31 +0000
@@ -2351,6 +2351,11 @@
                     paramString += view.userOrgUnit[i] + (i < view.userOrgUnit.length - 1 ? ';' : '');
                 }
             }
+            
+            // relative period date
+            if (view.relativePeriodDate) {
+                paramString += '&relativePeriodDate=' + view.relativePeriodDate;
+            }
 
 			success = function(json) {
 				var response = gis.api.response.Response(json),
@@ -3289,6 +3294,25 @@
                 return dataDimensions;
             };
 
+            util.date = {};
+
+            util.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
             util.message = {};
 
             util.message.alert = function(obj) {
@@ -3641,6 +3665,11 @@
                     if (Ext.Array.from(config.userOrgUnit).length) {
                         layout.userOrgUnit = Ext.Array.from(config.userOrgUnit);
                     }
+                    
+                    // relative period date
+                    if (util.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
 
                     return Ext.apply(layout, forceApplyConfig);
                 }();

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/map.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/map.js	2015-08-24 16:07:14 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-mapping/scripts/map.js	2015-09-02 18:25:31 +0000
@@ -3808,6 +3808,11 @@
                     paramString += view.userOrgUnit[i] + (i < view.userOrgUnit.length - 1 ? ';' : '');
                 }
             }
+            
+            // relative period date
+            if (view.relativePeriodDate) {
+                paramString += '&relativePeriodDate=' + view.relativePeriodDate;
+            }
 
 			success = function(json) {
 				var response = gis.api.response.Response(json),
@@ -4746,6 +4751,25 @@
                 return dataDimensions;
             };
 
+            util.date = {};
+
+            util.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
             util.message = {};
 
             util.message.alert = function(obj) {
@@ -5098,6 +5122,11 @@
                     if (Ext.Array.from(config.userOrgUnit).length) {
                         layout.userOrgUnit = Ext.Array.from(config.userOrgUnit);
                     }
+                    
+                    // relative period date
+                    if (util.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
 
                     return Ext.apply(layout, forceApplyConfig);
                 }();
@@ -5214,7 +5243,6 @@
 		return gis;
 	};
 
-
     // MAPFISH (mapfish.js)
 
     (function() {

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/core.js	2015-08-19 21:26:45 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/core.js	2015-09-02 18:25:31 +0000
@@ -584,6 +584,11 @@
                         layout.program = config.program;
                     }
 
+                    // relative period date
+                    if (support.prototype.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
+
                     // validate
 					if (!validateSpecialCases()) {
 						return;
@@ -819,6 +824,26 @@
 				return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, conf.report.digitGroupSeparator[separator]);
 			};
 
+                // date
+            support.prototype.date = {};
+
+            support.prototype.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
 			// color
 			support.color = {};
 
@@ -2091,6 +2116,11 @@
                     paramString += '&program=' + xLayout.program.id;
                 }
 
+                // relative period date
+                if (xLayout.relativePeriodDate) {
+                    paramString += '&relativePeriodDate=' + xLayout.relativePeriodDate;
+                }
+
 				return paramString.replace(/#/g, '.');
 			};
 

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/table.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/table.js	2015-08-19 21:26:45 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-pivot/scripts/table.js	2015-09-02 18:25:31 +0000
@@ -586,6 +586,11 @@
                         layout.program = config.program;
                     }
 
+                    // relative period date
+                    if (support.prototype.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
+
                     // validate
 					if (!validateSpecialCases()) {
 						return;
@@ -821,6 +826,26 @@
 				return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, conf.report.digitGroupSeparator[separator]);
 			};
 
+                // date
+            support.prototype.date = {};
+
+            support.prototype.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
 			// color
 			support.color = {};
 
@@ -2093,6 +2118,11 @@
                     paramString += '&program=' + xLayout.program.id;
                 }
 
+                // relative period date
+                if (xLayout.relativePeriodDate) {
+                    paramString += '&relativePeriodDate=' + xLayout.relativePeriodDate;
+                }
+
 				return paramString.replace(/#/g, '.');
 			};
 

=== modified file 'dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/core.js'
--- dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/core.js	2015-08-19 21:30:33 +0000
+++ dhis-2/dhis-web/dhis-web-apps/src/main/webapp/dhis-web-visualizer/scripts/core.js	2015-09-02 18:25:31 +0000
@@ -1156,6 +1156,11 @@
                         layout.program = config.program;
                     }
 
+                    // relative period date
+                    if (support.prototype.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
+
                     // style
                     if (Ext.isObject(config.domainAxisStyle)) {
                         layout.domainAxisStyle = config.domainAxisStyle;
@@ -1173,6 +1178,7 @@
                         layout.seriesStyle = config.seriesStyle;
                     }
 
+                    // validate
 					if (!validateSpecialCases()) {
 						return;
 					}
@@ -1428,7 +1434,28 @@
 
                 return variable;
 			};
-		}());
+
+                // date
+            support.prototype.date = {};
+
+            support.prototype.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
+        }());
 
 		// service
 		(function() {
@@ -2343,6 +2370,11 @@
                     paramString += '&program=' + xLayout.program.id;
                 }
 
+                // relative period date
+                if (xLayout.relativePeriodDate) {
+                    paramString += '&relativePeriodDate=' + xLayout.relativePeriodDate;
+                }
+
                 return paramString.replace(/#/g, '.');
             };
 

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/eventchart.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/eventchart.js	2015-05-13 16:59:59 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/eventchart.js	2015-09-02 18:25:31 +0000
@@ -717,33 +717,7 @@
 					{id: 'FinancialJuly', name: EV.i18n.financial_july},
 					{id: 'FinancialApril', name: EV.i18n.financial_april}
 				],
-                relativePeriods: [
-                    'THIS_WEEK',
-                    'LAST_WEEK',
-                    'LAST_4_WEEKS',
-                    'LAST_12_WEEKS',
-                    'LAST_52_WEEKS',
-                    'THIS_MONTH',
-                    'LAST_MONTH',
-                    'LAST_3_MONTHS',
-                    'LAST_6_MONTHS',
-                    'LAST_12_MONTHS',
-                    'THIS_BIMONTH',
-                    'LAST_BIMONTH',
-                    'LAST_6_BIMONTHS',
-                    'THIS_QUARTER',
-                    'LAST_QUARTER',
-                    'LAST_4_QUARTERS',
-                    'THIS_SIX_MONTH',
-                    'LAST_SIX_MONTH',
-                    'LAST_2_SIXMONTHS',
-                    'THIS_FINANCIAL_YEAR',
-                    'LAST_FINANCIAL_YEAR',
-                    'LAST_5_FINANCIAL_YEARS',
-                    'THIS_YEAR',
-                    'LAST_YEAR',
-                    'LAST_5_YEARS'
-                ]
+                relativePeriods: []
 			};
 
                 // aggregation type
@@ -772,7 +746,7 @@
                 west_fill_accordion_indicator: 56,
                 west_fill_accordion_dataelement: 59,
                 west_fill_accordion_dataset: 31,
-                west_fill_accordion_period: 330,
+                west_fill_accordion_period: 335,
                 west_fill_accordion_organisationunit: 58,
                 west_maxheight_accordion_indicator: 450,
                 west_maxheight_accordion_dataset: 350,
@@ -954,7 +928,7 @@
 
                 // sortOrder: number
 
-                // outputType: string ('EVENT') - 'EVENT', 'TRACKED_ENTITY_INSTANCE', 'ENROLLMENT'
+                // outputType: string ('EVENT') - 'EVENT', 'TRACKED_ENTITY_IEVTANCE', 'ENROLLMENT'
 
                 // rangeAxisMaxValue: number
 
@@ -1118,7 +1092,7 @@
 
                     // period
                     if (!Ext.Array.contains(objectNames, 'pe') && !(config.startDate && config.endDate)) {
-                        ns.alert('At least one fixed period, one relative period or start/end dates must be specified.');
+                        ns.alert('At least one fixed period, one relative period or start/end dates must be specified');
                         return;
                     }
 
@@ -1128,7 +1102,7 @@
 
 					// column
 					if (!config.columns) {
-						ns.alert('No series items selected.');
+						ns.alert('No series items selected');
 						return;
 					}
 
@@ -1140,7 +1114,7 @@
 
 					// row
 					if (!config.rows) {
-						ns.alert('No category items selected.');
+						ns.alert('No category items selected');
 						return;
 					}
 
@@ -1218,6 +1192,11 @@
 					//layout.sortOrder = Ext.isNumber(config.sortOrder) ? config.sortOrder : 0;
 					//layout.topLimit = Ext.isNumber(config.topLimit) ? config.topLimit : 0;
 
+                    // relative period date
+                    if (support.prototype.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
+                    
                     // style
                     if (Ext.isObject(config.domainAxisStyle)) {
                         layout.domainAxisStyle = config.domainAxisStyle;
@@ -1654,6 +1633,26 @@
 				return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, conf.report.digitGroupSeparator[separator]);
 			};
 
+                // date
+            support.prototype.date = {};
+
+            support.prototype.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
 			// color
 			support.color = {};
 
@@ -2637,8 +2636,8 @@
                     names,
 					headers,
                     booleanNameMap = {
-                        'true': EV.i18n.yes || 'Yes',
-                        'false': EV.i18n.no || 'No'
+                        '1': EV.i18n.yes || 'Yes',
+                        '0': EV.i18n.no || 'No'
                     };
 
 				response = Ext.clone(response);
@@ -2695,6 +2694,60 @@
                             support.prototype.array.sort(objects, 'ASC', 'sortingId');
                             header.ids = Ext.Array.pluck(objects, 'id');
                         }
+                        else if (header.type === 'java.lang.Boolean') {
+							var objects = [];
+
+                            for (var k = 0, id, fullId, name, isHierarchy; k < response.rows.length; k++) {
+                                id = response.rows[k][i] || emptyId;
+
+                                // hide NA data
+                                if (xLayout.hideNaData && id === emptyId) {
+                                    continue;
+                                }
+
+                                fullId = header.name + id;
+                                isHierarchy = service.layout.isHierarchy(xLayout, response, id);
+
+                                // add dimension name prefix if not pe/ou
+                                name = isMeta ? '' : header.column + ' ';
+
+                                // add hierarchy if ou and showHierarchy
+                                name = isHierarchy ? service.layout.getHierarchyName(ouHierarchy, names, id) : (names[id] || id);
+
+                                names[fullId] = name;
+
+                                // update rows
+                                response.rows[k][i] = fullId;
+
+                                // update ou hierarchy
+                                if (isHierarchy) {
+									ouHierarchy[fullId] = ouHierarchy[id];
+								}
+
+                                // update boolean metadata
+                                response.metaData.booleanNames[id] = booleanNameMap[id];
+                                response.metaData.booleanNames[fullId] = booleanNameMap[id];
+
+								objects.push({
+									id: fullId,
+									sortingId: id
+								});
+                            }
+
+                            // sort
+                            objects.sort(function(a, b) {
+                                if (a.sortingId === emptyId) {
+                                    return 1;
+                                }
+                                else if (b.sortingId === emptyId) {
+                                    return -1;
+                                }
+
+                                return a.sortingId - b.sortingId;
+                            });
+
+                            header.ids = Ext.Array.pluck(objects, 'id');
+                        }
                         else if (header.name === 'pe') {
                             var selectedItems = xLayout.dimensionNameIdsMap['pe'],
                                 isRelative = false;
@@ -2742,15 +2795,9 @@
 									ouHierarchy[fullId] = ouHierarchy[id];
 								}
 
-                                // update boolean metadata
-                                if (header.type === 'java.lang.Boolean') {
-                                    response.metaData.booleanNames[id] = booleanNameMap[id];
-                                    response.metaData.booleanNames[fullId] = booleanNameMap[id];
-                                }
-
 								objects.push({
 									id: fullId,
-									sortingId: header.name === 'pe' ? fullId : name
+									sortingId: name
 								});
                             }
 
@@ -2900,24 +2947,42 @@
 			// message
 			web.message = web.message || {};
 
-			web.message.alert = function(msg, type) {
+			web.message.alert = function(obj) {
                 var config = {},
+                    type,
                     window;
 
-                if (!msg) {
+                if (!obj || (Ext.isObject(obj) && !obj.message && !obj.responseText)) {
                     return;
                 }
 
-                type = type || 'error';
-
-				config.title = type === 'error' ? EV.i18n.error : (type === 'warning' ? EV.i18n.warning : EV.i18n.info);
+                // if response object
+                if (Ext.isObject(obj) && obj.responseText && !obj.message) {
+                    obj = Ext.decode(obj.responseText);
+                }
+
+                // if string
+                if (Ext.isString(obj)) {
+                    obj = {
+                        status: 'ERROR',
+                        message: obj
+                    };
+                }
+
+                // web message
+                type = (obj.status || 'INFO').toLowerCase();
+
+				config.title = obj.status;
 				config.iconCls = 'ns-window-title-messagebox ' + type;
 
                 // html
-                config.html = msg + (msg.substr(msg.length - 1) === '.' ? '' : '.');
+                config.html = '';
+                config.html += obj.httpStatusCode ? 'Code: ' + obj.httpStatusCode + '<br>' : '';
+                config.html += obj.httpStatus ? 'Status: ' + obj.httpStatus + '<br><br>' : '';
+                config.html += obj.message + (obj.message.substr(obj.message.length - 1) === '.' ? '' : '.');
 
                 // bodyStyle
-                config.bodyStyle = 'padding: 10px; background: #fff; max-width: 350px; max-height: ' + ns.app.centerRegion.getHeight() / 2 + 'px';
+                config.bodyStyle = 'padding: 12px; background: #fff; max-width: 600px; max-height: ' + ns.app.centerRegion.getHeight() / 2 + 'px';
 
                 // destroy handler
                 config.modal = true;
@@ -3048,6 +3113,11 @@
                     paramString += '&collapseDataDimensions=true';
                 }
 
+                // relative period date
+                if (layout.relativePeriodDate) {
+                    paramString += '&relativePeriodDate=' + layout.relativePeriodDate;
+                }
+
                 return paramString;
             };
 
@@ -3064,7 +3134,10 @@
 
                 msg += '\n\n' + 'Hint: A good way to reduce the number of items is to use relative periods and level/group organisation unit selection modes.';
 
-                ns.alert(msg, 'warning');
+                ns.alert({
+                    status: 'INFO',
+                    message: msg
+                });
 			};
 
 			// report
@@ -4599,7 +4672,7 @@
                             labelFont: labelFont
                         }
                     });
-
+                    
                     return chart;
                 };
 
@@ -4646,6 +4719,8 @@
 		ns.core.support = support;
 		ns.core.service = service;
 		ns.core.web = web;
+
+		return ns;
 	};
 
 	// PLUGIN

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/eventreport.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/eventreport.js	2015-05-13 16:59:59 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/eventreport.js	2015-09-02 18:25:31 +0000
@@ -167,33 +167,7 @@
 					{id: 'FinancialJuly', name: ER.i18n.financial_july},
 					{id: 'FinancialApril', name: ER.i18n.financial_april}
 				],
-                relativePeriods: [
-                    'THIS_WEEK',
-                    'LAST_WEEK',
-                    'LAST_4_WEEKS',
-                    'LAST_12_WEEKS',
-                    'LAST_52_WEEKS',
-                    'THIS_MONTH',
-                    'LAST_MONTH',
-                    'LAST_3_MONTHS',
-                    'LAST_6_MONTHS',
-                    'LAST_12_MONTHS',
-                    'THIS_BIMONTH',
-                    'LAST_BIMONTH',
-                    'LAST_6_BIMONTHS',
-                    'THIS_QUARTER',
-                    'LAST_QUARTER',
-                    'LAST_4_QUARTERS',
-                    'THIS_SIX_MONTH',
-                    'LAST_SIX_MONTH',
-                    'LAST_2_SIXMONTHS',
-                    'THIS_FINANCIAL_YEAR',
-                    'LAST_FINANCIAL_YEAR',
-                    'LAST_5_FINANCIAL_YEARS',
-                    'THIS_YEAR',
-                    'LAST_YEAR',
-                    'LAST_5_YEARS'
-                ]
+                relativePeriods: []
 			};
 
                 // aggregation type
@@ -222,7 +196,7 @@
                 west_fill_accordion_indicator: 56,
                 west_fill_accordion_dataelement: 59,
                 west_fill_accordion_dataset: 31,
-                west_fill_accordion_period: 330,
+                west_fill_accordion_period: 335,
                 west_fill_accordion_organisationunit: 58,
                 west_maxheight_accordion_indicator: 450,
                 west_maxheight_accordion_dataset: 350,
@@ -401,7 +375,7 @@
 
                 // collapseDataDimensions: boolean (false)
 
-                // outputType: string ('EVENT') - 'EVENT', 'TRACKED_ENTITY_INSTANCE', 'ENROLLMENT'
+                // outputType: string ('EVENT') - 'EVENT', 'TRACKED_ENTITY_IERTANCE', 'ENROLLMENT'
 
                 // aggregationType: string ('default') - 'default', 'count', 'sum'
 
@@ -614,6 +588,11 @@
 					//layout.sortOrder = Ext.isNumber(config.sortOrder) ? config.sortOrder : 0;
 					//layout.topLimit = Ext.isNumber(config.topLimit) ? config.topLimit : 0;
 
+                    // relative period date
+                    if (support.prototype.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
+
 					if (!validateSpecialCases()) {
 						return;
 					}
@@ -680,7 +659,7 @@
 
 					if (!(Ext.isArray(config.rows) && config.rows.length > 0)) {
 						//alert('No values found');
-						//return;
+						//return; // for ER, not for PT
 					}
 
 					if (config.rows.length > 0 && config.headers.length !== config.rows[0].length) {
@@ -990,6 +969,26 @@
 				return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, conf.report.digitGroupSeparator[separator]);
 			};
 
+                // date
+            support.prototype.date = {};
+
+            support.prototype.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
 			// color
 			support.color = {};
 
@@ -1968,8 +1967,8 @@
                     names,
 					headers,
                     booleanNameMap = {
-                        'true': ER.i18n.yes || 'Yes',
-                        'false': ER.i18n.no || 'No'
+                        '1': ER.i18n.yes || 'Yes',
+                        '0': ER.i18n.no || 'No'
                     };
 
 				response = Ext.clone(response);
@@ -2026,6 +2025,60 @@
                             support.prototype.array.sort(objects, 'ASC', 'sortingId');
                             header.ids = Ext.Array.pluck(objects, 'id');
                         }
+                        else if (header.type === 'java.lang.Boolean') {
+							var objects = [];
+
+                            for (var k = 0, id, fullId, name, isHierarchy; k < response.rows.length; k++) {
+                                id = response.rows[k][i] || emptyId;
+
+                                // hide NA data
+                                if (xLayout.hideNaData && id === emptyId) {
+                                    continue;
+                                }
+
+                                fullId = header.name + id;
+                                isHierarchy = service.layout.isHierarchy(xLayout, response, id);
+
+                                // add dimension name prefix if not pe/ou
+                                name = isMeta ? '' : header.column + ' ';
+
+                                // add hierarchy if ou and showHierarchy
+                                name = isHierarchy ? service.layout.getHierarchyName(ouHierarchy, names, id) : (names[id] || id);
+
+                                names[fullId] = name;
+
+                                // update rows
+                                response.rows[k][i] = fullId;
+
+                                // update ou hierarchy
+                                if (isHierarchy) {
+									ouHierarchy[fullId] = ouHierarchy[id];
+								}
+
+                                // update boolean metadata
+                                response.metaData.booleanNames[id] = booleanNameMap[id];
+                                response.metaData.booleanNames[fullId] = booleanNameMap[id];
+
+								objects.push({
+									id: fullId,
+									sortingId: id
+								});
+                            }
+
+                            // sort
+                            objects.sort(function(a, b) {
+                                if (a.sortingId === emptyId) {
+                                    return 1;
+                                }
+                                else if (b.sortingId === emptyId) {
+                                    return -1;
+                                }
+
+                                return a.sortingId - b.sortingId;
+                            });
+
+                            header.ids = Ext.Array.pluck(objects, 'id');
+                        }
                         else if (header.name === 'pe') {
                             var selectedItems = xLayout.dimensionNameIdsMap['pe'],
                                 isRelative = false;
@@ -2073,15 +2126,9 @@
 									ouHierarchy[fullId] = ouHierarchy[id];
 								}
 
-                                // update boolean metadata
-                                if (header.type === 'java.lang.Boolean') {
-                                    response.metaData.booleanNames[id] = booleanNameMap[id];
-                                    response.metaData.booleanNames[fullId] = booleanNameMap[id];
-                                }
-
 								objects.push({
 									id: fullId,
-									sortingId: header.name === 'pe' ? fullId : name
+									sortingId: name
 								});
                             }
 
@@ -2262,26 +2309,37 @@
 			};
 
 			web.window.addHideOnBlurHandler = function(w) {
-				var el = Ext.get(Ext.query('.x-mask')[0]);
-
-				el.on('click', function() {
-					if (w.hideOnBlur) {
-						w.hide();
-					}
-				});
+				var masks = Ext.query('.x-mask');
+
+                for (var i = 0, el; i < masks.length; i++) {
+                    el = Ext.get(masks[i]);
+
+                    if (el.getWidth() == Ext.getBody().getWidth()) {
+                        el.on('click', function() {
+                            if (w.hideOnBlur) {
+                                w.hide();
+                            }
+                        });
+                    }
+                }
 
 				w.hasHideOnBlurHandler = true;
 			};
 
 			web.window.addDestroyOnBlurHandler = function(w) {
-				var maskElements = Ext.query('.x-mask'),
-                    el = Ext.get(maskElements[0]);
-
-				el.on('click', function() {
-					if (w.destroyOnBlur) {
-						w.destroy();
-					}
-				});
+				var masks = Ext.query('.x-mask');
+
+                for (var i = 0, el; i < masks.length; i++) {
+                    el = Ext.get(masks[i]);
+
+                    if (el.getWidth() == Ext.getBody().getWidth()) {
+                        el.on('click', function() {
+                            if (w.destroyOnBlur) {
+                                w.destroy();
+                            }
+                        });
+                    }
+                }
 
 				w.hasDestroyOnBlurHandler = true;
 			};
@@ -2289,24 +2347,42 @@
 			// message
 			web.message = {};
 
-			web.message.alert = function(msg, type) {
+			web.message.alert = function(obj) {
                 var config = {},
+                    type,
                     window;
 
-                if (!msg) {
+                if (!obj || (Ext.isObject(obj) && !obj.message && !obj.responseText)) {
                     return;
                 }
 
-                type = type || 'error';
-
-				config.title = type === 'error' ? ER.i18n.error : (type === 'warning' ? ER.i18n.warning : ER.i18n.info);
+                // if response object
+                if (Ext.isObject(obj) && obj.responseText && !obj.message) {
+                    obj = Ext.decode(obj.responseText);
+                }
+
+                // if string
+                if (Ext.isString(obj)) {
+                    obj = {
+                        status: 'ERROR',
+                        message: obj
+                    };
+                }
+
+                // web message
+                type = (obj.status || 'INFO').toLowerCase();
+
+				config.title = obj.status;
 				config.iconCls = 'ns-window-title-messagebox ' + type;
 
                 // html
-                config.html = msg + (msg.substr(msg.length - 1) === '.' ? '' : '.');
+                config.html = '';
+                config.html += obj.httpStatusCode ? 'Code: ' + obj.httpStatusCode + '<br>' : '';
+                config.html += obj.httpStatus ? 'Status: ' + obj.httpStatus + '<br><br>' : '';
+                config.html += obj.message + (obj.message.substr(obj.message.length - 1) === '.' ? '' : '.');
 
                 // bodyStyle
-                config.bodyStyle = 'padding: 10px; background: #fff; max-width: 350px; max-height: ' + ns.app.centerRegion.getHeight() / 2 + 'px';
+                config.bodyStyle = 'padding: 12px; background: #fff; max-width: 600px; max-height: ' + ns.app.centerRegion.getHeight() / 2 + 'px';
 
                 // destroy handler
                 config.modal = true;
@@ -2460,6 +2536,11 @@
                 if (view.collapseDataDimensions) {
                     paramString += '&collapseDataDimensions=true';
                 }
+                
+                // relative period date
+                if (view.relativePeriodDate) {
+                    paramString += '&relativePeriodDate=' + view.relativePeriodDate;
+                }
 
                 return paramString;
             };
@@ -2477,7 +2558,10 @@
 
                 msg += '\n\n' + 'Hint: A good way to reduce the number of items is to use relative periods and level/group organisation unit selection modes.';
 
-                ns.alert(msg, 'warning');
+                ns.alert({
+                    status: 'INFO',
+                    message: msg
+                });
 			};
 
 			// report
@@ -3381,6 +3465,10 @@
 					rows = xResponse.rows,
                     names = xResponse.metaData.names,
                     optionNames = xResponse.metaData.optionNames,
+                    booleanNames = {
+                        '1': ER.i18n.yes,
+                        '0': ER.i18n.no
+                    },
                     pager = xResponse.metaData.pager,
                     count = pager.page * pager.pageSize - pager.pageSize
 					cls = 'pivot',
@@ -3418,8 +3506,7 @@
 					for (var j = 0, str, header, name; j < dimensionHeaders.length; j++) {
 						header = dimensionHeaders[j];
 						str = row[header.index];
-                        //str = names.hasOwnProperty(str) ? names[str] : str;
-                        str = optionNames[header.name + str] || optionNames[str] || names[str] || str;
+                        str = optionNames[header.name + str] || optionNames[str] || booleanNames[str] || names[str] || str;
 						name = web.report.query.format(str);
 
 						//if (header.name === 'ouname' && layout.showHierarchy) {

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/map.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/map.js	2015-08-24 16:07:14 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/map.js	2015-09-02 18:25:31 +0000
@@ -3808,6 +3808,11 @@
                     paramString += view.userOrgUnit[i] + (i < view.userOrgUnit.length - 1 ? ';' : '');
                 }
             }
+            
+            // relative period date
+            if (view.relativePeriodDate) {
+                paramString += '&relativePeriodDate=' + view.relativePeriodDate;
+            }
 
 			success = function(json) {
 				var response = gis.api.response.Response(json),
@@ -4746,6 +4751,25 @@
                 return dataDimensions;
             };
 
+            util.date = {};
+
+            util.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
             util.message = {};
 
             util.message.alert = function(obj) {
@@ -5098,6 +5122,11 @@
                     if (Ext.Array.from(config.userOrgUnit).length) {
                         layout.userOrgUnit = Ext.Array.from(config.userOrgUnit);
                     }
+                    
+                    // relative period date
+                    if (util.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
 
                     return Ext.apply(layout, forceApplyConfig);
                 }();
@@ -5214,7 +5243,6 @@
 		return gis;
 	};
 
-
     // MAPFISH (mapfish.js)
 
     (function() {

=== modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/table.js'
--- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/table.js	2015-08-19 21:26:45 +0000
+++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/plugin/table.js	2015-09-02 18:25:31 +0000
@@ -586,6 +586,11 @@
                         layout.program = config.program;
                     }
 
+                    // relative period date
+                    if (support.prototype.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
+
                     // validate
 					if (!validateSpecialCases()) {
 						return;
@@ -821,6 +826,26 @@
 				return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, conf.report.digitGroupSeparator[separator]);
 			};
 
+                // date
+            support.prototype.date = {};
+
+            support.prototype.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
 			// color
 			support.color = {};
 
@@ -2093,6 +2118,11 @@
                     paramString += '&program=' + xLayout.program.id;
                 }
 
+                // relative period date
+                if (xLayout.relativePeriodDate) {
+                    paramString += '&relativePeriodDate=' + xLayout.relativePeriodDate;
+                }
+
 				return paramString.replace(/#/g, '.');
 			};
 

=== modified file 'dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/eventchart.js'
--- dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/eventchart.js	2015-05-13 16:59:59 +0000
+++ dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/eventchart.js	2015-09-02 18:25:31 +0000
@@ -717,33 +717,7 @@
 					{id: 'FinancialJuly', name: EV.i18n.financial_july},
 					{id: 'FinancialApril', name: EV.i18n.financial_april}
 				],
-                relativePeriods: [
-                    'THIS_WEEK',
-                    'LAST_WEEK',
-                    'LAST_4_WEEKS',
-                    'LAST_12_WEEKS',
-                    'LAST_52_WEEKS',
-                    'THIS_MONTH',
-                    'LAST_MONTH',
-                    'LAST_3_MONTHS',
-                    'LAST_6_MONTHS',
-                    'LAST_12_MONTHS',
-                    'THIS_BIMONTH',
-                    'LAST_BIMONTH',
-                    'LAST_6_BIMONTHS',
-                    'THIS_QUARTER',
-                    'LAST_QUARTER',
-                    'LAST_4_QUARTERS',
-                    'THIS_SIX_MONTH',
-                    'LAST_SIX_MONTH',
-                    'LAST_2_SIXMONTHS',
-                    'THIS_FINANCIAL_YEAR',
-                    'LAST_FINANCIAL_YEAR',
-                    'LAST_5_FINANCIAL_YEARS',
-                    'THIS_YEAR',
-                    'LAST_YEAR',
-                    'LAST_5_YEARS'
-                ]
+                relativePeriods: []
 			};
 
                 // aggregation type
@@ -772,7 +746,7 @@
                 west_fill_accordion_indicator: 56,
                 west_fill_accordion_dataelement: 59,
                 west_fill_accordion_dataset: 31,
-                west_fill_accordion_period: 330,
+                west_fill_accordion_period: 335,
                 west_fill_accordion_organisationunit: 58,
                 west_maxheight_accordion_indicator: 450,
                 west_maxheight_accordion_dataset: 350,
@@ -954,7 +928,7 @@
 
                 // sortOrder: number
 
-                // outputType: string ('EVENT') - 'EVENT', 'TRACKED_ENTITY_INSTANCE', 'ENROLLMENT'
+                // outputType: string ('EVENT') - 'EVENT', 'TRACKED_ENTITY_IEVTANCE', 'ENROLLMENT'
 
                 // rangeAxisMaxValue: number
 
@@ -1118,7 +1092,7 @@
 
                     // period
                     if (!Ext.Array.contains(objectNames, 'pe') && !(config.startDate && config.endDate)) {
-                        ns.alert('At least one fixed period, one relative period or start/end dates must be specified.');
+                        ns.alert('At least one fixed period, one relative period or start/end dates must be specified');
                         return;
                     }
 
@@ -1128,7 +1102,7 @@
 
 					// column
 					if (!config.columns) {
-						ns.alert('No series items selected.');
+						ns.alert('No series items selected');
 						return;
 					}
 
@@ -1140,7 +1114,7 @@
 
 					// row
 					if (!config.rows) {
-						ns.alert('No category items selected.');
+						ns.alert('No category items selected');
 						return;
 					}
 
@@ -1218,6 +1192,11 @@
 					//layout.sortOrder = Ext.isNumber(config.sortOrder) ? config.sortOrder : 0;
 					//layout.topLimit = Ext.isNumber(config.topLimit) ? config.topLimit : 0;
 
+                    // relative period date
+                    if (support.prototype.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
+                    
                     // style
                     if (Ext.isObject(config.domainAxisStyle)) {
                         layout.domainAxisStyle = config.domainAxisStyle;
@@ -1654,6 +1633,26 @@
 				return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, conf.report.digitGroupSeparator[separator]);
 			};
 
+                // date
+            support.prototype.date = {};
+
+            support.prototype.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
 			// color
 			support.color = {};
 
@@ -2637,8 +2636,8 @@
                     names,
 					headers,
                     booleanNameMap = {
-                        'true': EV.i18n.yes || 'Yes',
-                        'false': EV.i18n.no || 'No'
+                        '1': EV.i18n.yes || 'Yes',
+                        '0': EV.i18n.no || 'No'
                     };
 
 				response = Ext.clone(response);
@@ -2695,6 +2694,60 @@
                             support.prototype.array.sort(objects, 'ASC', 'sortingId');
                             header.ids = Ext.Array.pluck(objects, 'id');
                         }
+                        else if (header.type === 'java.lang.Boolean') {
+							var objects = [];
+
+                            for (var k = 0, id, fullId, name, isHierarchy; k < response.rows.length; k++) {
+                                id = response.rows[k][i] || emptyId;
+
+                                // hide NA data
+                                if (xLayout.hideNaData && id === emptyId) {
+                                    continue;
+                                }
+
+                                fullId = header.name + id;
+                                isHierarchy = service.layout.isHierarchy(xLayout, response, id);
+
+                                // add dimension name prefix if not pe/ou
+                                name = isMeta ? '' : header.column + ' ';
+
+                                // add hierarchy if ou and showHierarchy
+                                name = isHierarchy ? service.layout.getHierarchyName(ouHierarchy, names, id) : (names[id] || id);
+
+                                names[fullId] = name;
+
+                                // update rows
+                                response.rows[k][i] = fullId;
+
+                                // update ou hierarchy
+                                if (isHierarchy) {
+									ouHierarchy[fullId] = ouHierarchy[id];
+								}
+
+                                // update boolean metadata
+                                response.metaData.booleanNames[id] = booleanNameMap[id];
+                                response.metaData.booleanNames[fullId] = booleanNameMap[id];
+
+								objects.push({
+									id: fullId,
+									sortingId: id
+								});
+                            }
+
+                            // sort
+                            objects.sort(function(a, b) {
+                                if (a.sortingId === emptyId) {
+                                    return 1;
+                                }
+                                else if (b.sortingId === emptyId) {
+                                    return -1;
+                                }
+
+                                return a.sortingId - b.sortingId;
+                            });
+
+                            header.ids = Ext.Array.pluck(objects, 'id');
+                        }
                         else if (header.name === 'pe') {
                             var selectedItems = xLayout.dimensionNameIdsMap['pe'],
                                 isRelative = false;
@@ -2742,15 +2795,9 @@
 									ouHierarchy[fullId] = ouHierarchy[id];
 								}
 
-                                // update boolean metadata
-                                if (header.type === 'java.lang.Boolean') {
-                                    response.metaData.booleanNames[id] = booleanNameMap[id];
-                                    response.metaData.booleanNames[fullId] = booleanNameMap[id];
-                                }
-
 								objects.push({
 									id: fullId,
-									sortingId: header.name === 'pe' ? fullId : name
+									sortingId: name
 								});
                             }
 
@@ -2900,24 +2947,42 @@
 			// message
 			web.message = web.message || {};
 
-			web.message.alert = function(msg, type) {
+			web.message.alert = function(obj) {
                 var config = {},
+                    type,
                     window;
 
-                if (!msg) {
+                if (!obj || (Ext.isObject(obj) && !obj.message && !obj.responseText)) {
                     return;
                 }
 
-                type = type || 'error';
-
-				config.title = type === 'error' ? EV.i18n.error : (type === 'warning' ? EV.i18n.warning : EV.i18n.info);
+                // if response object
+                if (Ext.isObject(obj) && obj.responseText && !obj.message) {
+                    obj = Ext.decode(obj.responseText);
+                }
+
+                // if string
+                if (Ext.isString(obj)) {
+                    obj = {
+                        status: 'ERROR',
+                        message: obj
+                    };
+                }
+
+                // web message
+                type = (obj.status || 'INFO').toLowerCase();
+
+				config.title = obj.status;
 				config.iconCls = 'ns-window-title-messagebox ' + type;
 
                 // html
-                config.html = msg + (msg.substr(msg.length - 1) === '.' ? '' : '.');
+                config.html = '';
+                config.html += obj.httpStatusCode ? 'Code: ' + obj.httpStatusCode + '<br>' : '';
+                config.html += obj.httpStatus ? 'Status: ' + obj.httpStatus + '<br><br>' : '';
+                config.html += obj.message + (obj.message.substr(obj.message.length - 1) === '.' ? '' : '.');
 
                 // bodyStyle
-                config.bodyStyle = 'padding: 10px; background: #fff; max-width: 350px; max-height: ' + ns.app.centerRegion.getHeight() / 2 + 'px';
+                config.bodyStyle = 'padding: 12px; background: #fff; max-width: 600px; max-height: ' + ns.app.centerRegion.getHeight() / 2 + 'px';
 
                 // destroy handler
                 config.modal = true;
@@ -3048,6 +3113,11 @@
                     paramString += '&collapseDataDimensions=true';
                 }
 
+                // relative period date
+                if (layout.relativePeriodDate) {
+                    paramString += '&relativePeriodDate=' + layout.relativePeriodDate;
+                }
+
                 return paramString;
             };
 
@@ -3064,7 +3134,10 @@
 
                 msg += '\n\n' + 'Hint: A good way to reduce the number of items is to use relative periods and level/group organisation unit selection modes.';
 
-                ns.alert(msg, 'warning');
+                ns.alert({
+                    status: 'INFO',
+                    message: msg
+                });
 			};
 
 			// report
@@ -4599,7 +4672,7 @@
                             labelFont: labelFont
                         }
                     });
-
+                    
                     return chart;
                 };
 
@@ -4646,6 +4719,8 @@
 		ns.core.support = support;
 		ns.core.service = service;
 		ns.core.web = web;
+
+		return ns;
 	};
 
 	// PLUGIN

=== modified file 'dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/eventreport.js'
--- dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/eventreport.js	2015-05-13 16:59:59 +0000
+++ dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/eventreport.js	2015-09-02 18:25:31 +0000
@@ -167,33 +167,7 @@
 					{id: 'FinancialJuly', name: ER.i18n.financial_july},
 					{id: 'FinancialApril', name: ER.i18n.financial_april}
 				],
-                relativePeriods: [
-                    'THIS_WEEK',
-                    'LAST_WEEK',
-                    'LAST_4_WEEKS',
-                    'LAST_12_WEEKS',
-                    'LAST_52_WEEKS',
-                    'THIS_MONTH',
-                    'LAST_MONTH',
-                    'LAST_3_MONTHS',
-                    'LAST_6_MONTHS',
-                    'LAST_12_MONTHS',
-                    'THIS_BIMONTH',
-                    'LAST_BIMONTH',
-                    'LAST_6_BIMONTHS',
-                    'THIS_QUARTER',
-                    'LAST_QUARTER',
-                    'LAST_4_QUARTERS',
-                    'THIS_SIX_MONTH',
-                    'LAST_SIX_MONTH',
-                    'LAST_2_SIXMONTHS',
-                    'THIS_FINANCIAL_YEAR',
-                    'LAST_FINANCIAL_YEAR',
-                    'LAST_5_FINANCIAL_YEARS',
-                    'THIS_YEAR',
-                    'LAST_YEAR',
-                    'LAST_5_YEARS'
-                ]
+                relativePeriods: []
 			};
 
                 // aggregation type
@@ -222,7 +196,7 @@
                 west_fill_accordion_indicator: 56,
                 west_fill_accordion_dataelement: 59,
                 west_fill_accordion_dataset: 31,
-                west_fill_accordion_period: 330,
+                west_fill_accordion_period: 335,
                 west_fill_accordion_organisationunit: 58,
                 west_maxheight_accordion_indicator: 450,
                 west_maxheight_accordion_dataset: 350,
@@ -401,7 +375,7 @@
 
                 // collapseDataDimensions: boolean (false)
 
-                // outputType: string ('EVENT') - 'EVENT', 'TRACKED_ENTITY_INSTANCE', 'ENROLLMENT'
+                // outputType: string ('EVENT') - 'EVENT', 'TRACKED_ENTITY_IERTANCE', 'ENROLLMENT'
 
                 // aggregationType: string ('default') - 'default', 'count', 'sum'
 
@@ -614,6 +588,11 @@
 					//layout.sortOrder = Ext.isNumber(config.sortOrder) ? config.sortOrder : 0;
 					//layout.topLimit = Ext.isNumber(config.topLimit) ? config.topLimit : 0;
 
+                    // relative period date
+                    if (support.prototype.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
+
 					if (!validateSpecialCases()) {
 						return;
 					}
@@ -680,7 +659,7 @@
 
 					if (!(Ext.isArray(config.rows) && config.rows.length > 0)) {
 						//alert('No values found');
-						//return;
+						//return; // for ER, not for PT
 					}
 
 					if (config.rows.length > 0 && config.headers.length !== config.rows[0].length) {
@@ -990,6 +969,26 @@
 				return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, conf.report.digitGroupSeparator[separator]);
 			};
 
+                // date
+            support.prototype.date = {};
+
+            support.prototype.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
 			// color
 			support.color = {};
 
@@ -1968,8 +1967,8 @@
                     names,
 					headers,
                     booleanNameMap = {
-                        'true': ER.i18n.yes || 'Yes',
-                        'false': ER.i18n.no || 'No'
+                        '1': ER.i18n.yes || 'Yes',
+                        '0': ER.i18n.no || 'No'
                     };
 
 				response = Ext.clone(response);
@@ -2026,6 +2025,60 @@
                             support.prototype.array.sort(objects, 'ASC', 'sortingId');
                             header.ids = Ext.Array.pluck(objects, 'id');
                         }
+                        else if (header.type === 'java.lang.Boolean') {
+							var objects = [];
+
+                            for (var k = 0, id, fullId, name, isHierarchy; k < response.rows.length; k++) {
+                                id = response.rows[k][i] || emptyId;
+
+                                // hide NA data
+                                if (xLayout.hideNaData && id === emptyId) {
+                                    continue;
+                                }
+
+                                fullId = header.name + id;
+                                isHierarchy = service.layout.isHierarchy(xLayout, response, id);
+
+                                // add dimension name prefix if not pe/ou
+                                name = isMeta ? '' : header.column + ' ';
+
+                                // add hierarchy if ou and showHierarchy
+                                name = isHierarchy ? service.layout.getHierarchyName(ouHierarchy, names, id) : (names[id] || id);
+
+                                names[fullId] = name;
+
+                                // update rows
+                                response.rows[k][i] = fullId;
+
+                                // update ou hierarchy
+                                if (isHierarchy) {
+									ouHierarchy[fullId] = ouHierarchy[id];
+								}
+
+                                // update boolean metadata
+                                response.metaData.booleanNames[id] = booleanNameMap[id];
+                                response.metaData.booleanNames[fullId] = booleanNameMap[id];
+
+								objects.push({
+									id: fullId,
+									sortingId: id
+								});
+                            }
+
+                            // sort
+                            objects.sort(function(a, b) {
+                                if (a.sortingId === emptyId) {
+                                    return 1;
+                                }
+                                else if (b.sortingId === emptyId) {
+                                    return -1;
+                                }
+
+                                return a.sortingId - b.sortingId;
+                            });
+
+                            header.ids = Ext.Array.pluck(objects, 'id');
+                        }
                         else if (header.name === 'pe') {
                             var selectedItems = xLayout.dimensionNameIdsMap['pe'],
                                 isRelative = false;
@@ -2073,15 +2126,9 @@
 									ouHierarchy[fullId] = ouHierarchy[id];
 								}
 
-                                // update boolean metadata
-                                if (header.type === 'java.lang.Boolean') {
-                                    response.metaData.booleanNames[id] = booleanNameMap[id];
-                                    response.metaData.booleanNames[fullId] = booleanNameMap[id];
-                                }
-
 								objects.push({
 									id: fullId,
-									sortingId: header.name === 'pe' ? fullId : name
+									sortingId: name
 								});
                             }
 
@@ -2262,26 +2309,37 @@
 			};
 
 			web.window.addHideOnBlurHandler = function(w) {
-				var el = Ext.get(Ext.query('.x-mask')[0]);
-
-				el.on('click', function() {
-					if (w.hideOnBlur) {
-						w.hide();
-					}
-				});
+				var masks = Ext.query('.x-mask');
+
+                for (var i = 0, el; i < masks.length; i++) {
+                    el = Ext.get(masks[i]);
+
+                    if (el.getWidth() == Ext.getBody().getWidth()) {
+                        el.on('click', function() {
+                            if (w.hideOnBlur) {
+                                w.hide();
+                            }
+                        });
+                    }
+                }
 
 				w.hasHideOnBlurHandler = true;
 			};
 
 			web.window.addDestroyOnBlurHandler = function(w) {
-				var maskElements = Ext.query('.x-mask'),
-                    el = Ext.get(maskElements[0]);
-
-				el.on('click', function() {
-					if (w.destroyOnBlur) {
-						w.destroy();
-					}
-				});
+				var masks = Ext.query('.x-mask');
+
+                for (var i = 0, el; i < masks.length; i++) {
+                    el = Ext.get(masks[i]);
+
+                    if (el.getWidth() == Ext.getBody().getWidth()) {
+                        el.on('click', function() {
+                            if (w.destroyOnBlur) {
+                                w.destroy();
+                            }
+                        });
+                    }
+                }
 
 				w.hasDestroyOnBlurHandler = true;
 			};
@@ -2289,24 +2347,42 @@
 			// message
 			web.message = {};
 
-			web.message.alert = function(msg, type) {
+			web.message.alert = function(obj) {
                 var config = {},
+                    type,
                     window;
 
-                if (!msg) {
+                if (!obj || (Ext.isObject(obj) && !obj.message && !obj.responseText)) {
                     return;
                 }
 
-                type = type || 'error';
-
-				config.title = type === 'error' ? ER.i18n.error : (type === 'warning' ? ER.i18n.warning : ER.i18n.info);
+                // if response object
+                if (Ext.isObject(obj) && obj.responseText && !obj.message) {
+                    obj = Ext.decode(obj.responseText);
+                }
+
+                // if string
+                if (Ext.isString(obj)) {
+                    obj = {
+                        status: 'ERROR',
+                        message: obj
+                    };
+                }
+
+                // web message
+                type = (obj.status || 'INFO').toLowerCase();
+
+				config.title = obj.status;
 				config.iconCls = 'ns-window-title-messagebox ' + type;
 
                 // html
-                config.html = msg + (msg.substr(msg.length - 1) === '.' ? '' : '.');
+                config.html = '';
+                config.html += obj.httpStatusCode ? 'Code: ' + obj.httpStatusCode + '<br>' : '';
+                config.html += obj.httpStatus ? 'Status: ' + obj.httpStatus + '<br><br>' : '';
+                config.html += obj.message + (obj.message.substr(obj.message.length - 1) === '.' ? '' : '.');
 
                 // bodyStyle
-                config.bodyStyle = 'padding: 10px; background: #fff; max-width: 350px; max-height: ' + ns.app.centerRegion.getHeight() / 2 + 'px';
+                config.bodyStyle = 'padding: 12px; background: #fff; max-width: 600px; max-height: ' + ns.app.centerRegion.getHeight() / 2 + 'px';
 
                 // destroy handler
                 config.modal = true;
@@ -2460,6 +2536,11 @@
                 if (view.collapseDataDimensions) {
                     paramString += '&collapseDataDimensions=true';
                 }
+                
+                // relative period date
+                if (view.relativePeriodDate) {
+                    paramString += '&relativePeriodDate=' + view.relativePeriodDate;
+                }
 
                 return paramString;
             };
@@ -2477,7 +2558,10 @@
 
                 msg += '\n\n' + 'Hint: A good way to reduce the number of items is to use relative periods and level/group organisation unit selection modes.';
 
-                ns.alert(msg, 'warning');
+                ns.alert({
+                    status: 'INFO',
+                    message: msg
+                });
 			};
 
 			// report
@@ -3381,6 +3465,10 @@
 					rows = xResponse.rows,
                     names = xResponse.metaData.names,
                     optionNames = xResponse.metaData.optionNames,
+                    booleanNames = {
+                        '1': ER.i18n.yes,
+                        '0': ER.i18n.no
+                    },
                     pager = xResponse.metaData.pager,
                     count = pager.page * pager.pageSize - pager.pageSize
 					cls = 'pivot',
@@ -3418,8 +3506,7 @@
 					for (var j = 0, str, header, name; j < dimensionHeaders.length; j++) {
 						header = dimensionHeaders[j];
 						str = row[header.index];
-                        //str = names.hasOwnProperty(str) ? names[str] : str;
-                        str = optionNames[header.name + str] || optionNames[str] || names[str] || str;
+                        str = optionNames[header.name + str] || optionNames[str] || booleanNames[str] || names[str] || str;
 						name = web.report.query.format(str);
 
 						//if (header.name === 'ouname' && layout.showHierarchy) {

=== modified file 'dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/map.js'
--- dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/map.js	2015-08-24 16:07:14 +0000
+++ dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/map.js	2015-09-02 18:25:31 +0000
@@ -3808,6 +3808,11 @@
                     paramString += view.userOrgUnit[i] + (i < view.userOrgUnit.length - 1 ? ';' : '');
                 }
             }
+            
+            // relative period date
+            if (view.relativePeriodDate) {
+                paramString += '&relativePeriodDate=' + view.relativePeriodDate;
+            }
 
 			success = function(json) {
 				var response = gis.api.response.Response(json),
@@ -4746,6 +4751,25 @@
                 return dataDimensions;
             };
 
+            util.date = {};
+
+            util.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
             util.message = {};
 
             util.message.alert = function(obj) {
@@ -5098,6 +5122,11 @@
                     if (Ext.Array.from(config.userOrgUnit).length) {
                         layout.userOrgUnit = Ext.Array.from(config.userOrgUnit);
                     }
+                    
+                    // relative period date
+                    if (util.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
 
                     return Ext.apply(layout, forceApplyConfig);
                 }();
@@ -5214,7 +5243,6 @@
 		return gis;
 	};
 
-
     // MAPFISH (mapfish.js)
 
     (function() {

=== modified file 'dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/table.js'
--- dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/table.js	2015-08-19 21:26:45 +0000
+++ dhis-2/dhis-web/dhis-web-dashboard-integration/src/main/webapp/dhis-web-dashboard-integration/plugin/table.js	2015-09-02 18:25:31 +0000
@@ -586,6 +586,11 @@
                         layout.program = config.program;
                     }
 
+                    // relative period date
+                    if (support.prototype.date.getYYYYMMDD(config.relativePeriodDate)) {
+                        layout.relativePeriodDate = support.prototype.date.getYYYYMMDD(config.relativePeriodDate);
+                    }
+
                     // validate
 					if (!validateSpecialCases()) {
 						return;
@@ -821,6 +826,26 @@
 				return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, conf.report.digitGroupSeparator[separator]);
 			};
 
+                // date
+            support.prototype.date = {};
+
+            support.prototype.date.getYYYYMMDD = function(param) {
+                if (!Ext.isString(param)) {
+                    if (!(Object.prototype.toString.call(param) === '[object Date]' && param.toString() !== 'Invalid date')) {
+                        return null;
+                    }
+                }
+
+                var date = new Date(param),
+                    month = '' + (1 + date.getMonth()),
+                    day = '' + date.getDate();
+
+                month = month.length === 1 ? '0' + month : month;
+                day = day.length === 1 ? '0' + day : day;
+
+                return date.getFullYear() + '-' + month + '-' + day;
+            };
+
 			// color
 			support.color = {};
 
@@ -2093,6 +2118,11 @@
                     paramString += '&program=' + xLayout.program.id;
                 }
 
+                // relative period date
+                if (xLayout.relativePeriodDate) {
+                    paramString += '&relativePeriodDate=' + xLayout.relativePeriodDate;
+                }
+
 				return paramString.replace(/#/g, '.');
 			};