From 74a17299c702f14ad957f408d4d09d38e620a6ac Mon Sep 17 00:00:00 2001 From: edodge Date: Thu, 30 Jun 2016 17:37:34 -0400 Subject: [PATCH 001/314] Add tiles API for web app redesign landing screen and tiles screen --- app/controllers/tiles/tiles.js | 104 +++++++++++++++++++++++++++++++++ app/helpers/queries.js | 10 +++- 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 app/controllers/tiles/tiles.js diff --git a/app/controllers/tiles/tiles.js b/app/controllers/tiles/tiles.js new file mode 100644 index 00000000..151d7511 --- /dev/null +++ b/app/controllers/tiles/tiles.js @@ -0,0 +1,104 @@ +'use strict'; + +var Queries = require('../../helpers/queries'); +var OverviewParser = require('../../helpers/overview_parser'); +var Translate = require('../../templates/helpers/t'); + +exports.showPage = { + handler: function(request, reply) { + // return reply.view('performance/overview'); + } +}; + +exports.getData = { + handler: function(request, reply) { + + var sequelize = request.server.plugins.sequelize.db.sequelize; + var region_code = request.query.region_code; + var role = request.auth.credentials.role; + var queryString = Queries.tiles(region_code, role); + + sequelize.query(queryString, { + type: sequelize.QueryTypes.SELECT + }).then(function(rows) { + + var overviewResponse = utils.flatten(rows[0]); + + var tilesResponse = utils.flatten(rows[1]); + + var stateResponse = utils.flatten(rows[2]); + + // Parse the overview response + var current_total = overviewResponse[0].current_total; + var delayed_total = overviewResponse[0].delayed_total; + var days_to_payment = overviewResponse[0].time_to_payment; + + var state_code = stateResponse[0].state_code; + + if (role === 'block') { + var tiles = d3.nest() + .key(function(d) { + return d.staff_id; + }) + .rollup(function(v) { + return { + 'name': v[0].name, + 'staff_id': v[0].staff_id, + 'designation': utils.getDesignation(v[0].task_assign,state_code), + 'mobile':v[0].mobile_no, + 'block_name':v[0].block_name, + 'current_total':v[0].current_total, + 'delayed_total':v[0].delayed_total, + 'delayed_musters': v.filter(function(d) { return d.type==='delayed_musters'; }).map(function(d) { + return [ + { + 'msr_no':d.msr_no, + 'panchayat_name':d.panchayat_name, + 'work_name':d.work_name, + 'work_code':d.work_code, + 'closure_date':d.end_date, + 'days_pending':d.days_pending + } + ]; + }), + 'current_musters': v.filter(function(d) { return d.type==='current_musters'; }).map(function(d) { + return [ + { + 'msr_no':d.msr_no, + 'panchayat_name':d.panchayat_name, + 'work_name':d.work_name, + 'work_code':d.work_code, + 'closure_date':d.end_date + } + ]; + }) + }; + }) + .entries(tilesResponse) + .map(function(d) { + return d.values; + }); + } + + if (role === 'district') { + + } + + var final_dict = { + 'overview': { + 'current_total':current_total, + 'delayed_total':delayed_total, + 'days_to_payment':days_to_payment, + 'total_transactions':total_transactions, + 'tiles_total': tiles.length + }, + 'tiles': tiles, + 'config': { + role: role + } + }; + + reply(final_dict); + }); + } +}; diff --git a/app/helpers/queries.js b/app/helpers/queries.js index c70858b3..5f0c3c41 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -36,6 +36,14 @@ exports.discretePerformance = function(REGION_CODE, ROLE) { }; +exports.tiles = function(REGION_CODE, ROLE) { + if (ROLE === 'block') { + return "SELECT a.current_total, b.delayed_total, c.time_to_payment, c.total_transactions FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code = '" + REGION_CODE + "') a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code = '" + REGION_CODE + "') b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment, IFNULL(SUM(total_transactions),0) AS total_transactions, 1 AS merge FROM block_delays_duration WHERE block_code = '" + REGION_CODE + "' AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + + "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, a.msr_no, a.work_name, a.work_code, a.panchayat_name, a.end_date, a.days_pending, a.step, a.type FROM (SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, a.block_name, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "') a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code = '" + REGION_CODE + "') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_name, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_name, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t5') b ON a.map_location = b.panchayat_code) a LEFT JOIN (SELECT count(*) AS current_total, staff_id FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "') a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code = '" + REGION_CODE + "') b ON a.map_location = b.panchayat_code GROUP BY staff_id) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id UNION SELECT count(*) AS delayed_total, staff_id FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL);" + + "SELECT DISTINCT state_code FROM blocks WHERE block_code = '" + REGION_CODE + "';"; + } +} + exports.panchayatPerformance = function(REGION_CODE) { return "SELECT panchayat_name as region_name from panchayats where panchayat_code=" + REGION_CODE + ";" + "SELECT panchayat_code AS region_code,panchayat_name AS region_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,0) mrc_mre,ROUND(mre_wlg_mean,0) mre_wlg,ROUND(wlg_wls_mean,0) wlg_wls,ROUND(wls_fto_mean,0) wls_fto,ROUND(fto_firstsign_mean,0) fto_sn1,ROUND(firstsign_secondsign_mean,0) sn1_sn2,ROUND(secondsign_processed_mean,0) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND panchayat_code ='" + REGION_CODE + "' ORDER BY panchayat_code, date;"; @@ -69,5 +77,5 @@ exports.cards = function(USER_ID) { "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + "SELECT block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY panchayat_code, date;" + "SELECT * FROM notifications WHERE user_id = '"+USER_ID+"';" + - "SELECT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;"; + "SELECT DISTINCT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"');"; }; \ No newline at end of file From 09abeff43b83eba6b9dabe74c4b18672225cfbbf Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Sun, 17 Jul 2016 16:11:58 +0530 Subject: [PATCH 002/314] Update dependencies --- .babelrc | 3 ++ .editorconfig | 7 +---- .eslintrc | 28 +++++++++++++++++ .jsbeautifyrc | 5 --- .jshintrc | 18 ----------- package.json | 86 +++++++++++++++++++++++++++------------------------ server.js | 8 ++--- 7 files changed, 81 insertions(+), 74 deletions(-) create mode 100644 .babelrc create mode 100644 .eslintrc delete mode 100644 .jsbeautifyrc delete mode 100644 .jshintrc diff --git a/.babelrc b/.babelrc new file mode 100644 index 00000000..ad8d1fe6 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets" : ["es2015", "react"] +} diff --git a/.editorconfig b/.editorconfig index 821d3ad5..6a6b1f42 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,17 +4,15 @@ root = true # Unix-style newlines with a newline ending every file - [**] end_of_line = lf insert_final_newline = true - # Standard at: https://github.com/felixge/node-style-guide - [**.js, **.json] trim_trailing_whitespace = true indent_style = tab +indent_size = 4 quote_type = single curly_bracket_next_line = false spaces_around_operators = true @@ -23,9 +21,6 @@ space_after_anonymous_functions = false spaces_in_brackets = false tab_size= 4 - # No standard. Please document a standard if different from .js - [**.md] indent_style = tab - diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..35601ce2 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,28 @@ +env: + browser: true + commonjs: true + es6: true + node: true +extends: 'eslint:recommended' +parserOptions: + ecmaFeatures: + experimentalObjectRestSpread: true + jsx: true + sourceType: module +plugins: + - react +rules: + linebreak-style: + - error + - unix + quotes: + - error + - single + semi: + - error + - always + curly: error + eqeqeq: error + no-empty: warn + no-console: off + no-unused-vars: off diff --git a/.jsbeautifyrc b/.jsbeautifyrc deleted file mode 100644 index db7b8f58..00000000 --- a/.jsbeautifyrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "js": { - "indent_size": 4 - } -} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index ec081e3a..00000000 --- a/.jshintrc +++ /dev/null @@ -1,18 +0,0 @@ -{ - "node": true, // Enable globals available when code is running inside of the NodeJS runtime environment. - "curly": false, // Require {} for every new block or scope. - "eqeqeq": true, // Require triple equals i.e. `===`. - "immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` - "latedef": true, // Prohibit variable use before definition. - "newcap": false, // Require capitalization of all constructor functions e.g. `new F()`. - "noarg": true, // Prohibit use of `arguments.caller` and `arguments.callee`. - "quotmark": "single", // Define quotes to string values. - "regexp": true, // Prohibit `.` and `[^...]` in regular expressions. - "undef": true, // Require all non-global variables be declared before they are used. - "strict": true, // Require `use strict` pragma in every file. - "indent": 4, // Specify indentation spacing - "devel": true, // Allow development statements e.g. `console.log();`. - "noempty": true, // Prohibit use of empty blocks. - "esnext" : true, - "browser":true -} diff --git a/package.json b/package.json index 641c0db4..a3a941a8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { "name": "paydash", - "version": "1.0.0", "description": "Workers Payment Dashboard", + "homepage": "https://github.com/hks-epod/paydash#readme", + "version": "1.0.0", "main": "index.js", "scripts": { "test": "node node_modules/lab/bin/lab", @@ -21,51 +22,54 @@ "bugs": { "url": "https://github.com/hks-epod/paydash/issues" }, - "homepage": "https://github.com/hks-epod/paydash#readme", + + "engines": { + "node": ">=4.0.0" + }, "dependencies": { - "bell": "^5.3.0", + "bell": "^7.9.3", "bistre": "^1.0.1", - "boom": "^2.8.0", - "confidence": "^1.2.0", - "crumb": "^4.0.3", - "d3": "^3.5.6", - "glob": "^5.0.14", - "glue": "^2.2.0", - "good": "^6.4.0", - "good-file": "^5.1.1", - "googleapis": "^2.1.7", - "gulp-util": "^3.0.7", - "handlebars": "^3.0.3", - "hapi": "^9.0.3", - "hapi-auth-cookie": "^3.1.0", + "boom": "^3.2.2", + "confidence": "^3.0.1", + "crumb": "^6.0.2", + "d3": "^4.1.1", + "glob": "^7.5.1", + "glue": "^3.3.0", + "good": "^7.1.0", + "good-file": "^6.0.1", + "googleapis": "11.0.1", + "handlebars": "^4.0.5", + "hapi": "^13.5.0", + "hapi-auth-cookie": "^6.1.1", "hapi-context-credentials": "^2.0.0", - "hoek": "^2.x.x", - "inert": "^3.0.1", - "joi": "^6.6.1", - "jquery": "^2.1.4", - "lodash": "^3.10.1", - "metrics-graphics": "^2.6.0", - "moment": "^2.10.6", - "mysql": "^2.9.0", - "request": "^2.65.0", - "sequelize": "^3.12.2", - "vision": "^3.0.0", - "visionary": "^3.0.1", - "yar": "^4.2.0" + "hoek": "^4.0.1", + "inert": "^4.0.1", + "joi": "^9.0.1", + "jquery": "^3.1.0", + "lodash": "^4.13.1", + "metrics-graphics": "^2.9.0", + "moment": "^2.14.1", + "mysql": "^2.11.1", + "request": "^2.73.0", + "sequelize": "^3.23.4", + "vision": "^4.1.0", + "visionary": "^6.0.0", + "yar": "^7.0.2" }, "devDependencies": { - "code": "^1.5.0", - "del": "^2.0.2", - "gulp": "^3.9.0", - "gulp-autoprefixer": "^3.0.1", - "gulp-jshint": "^1.11.2", - "gulp-less": "^3.0.3", - "gulp-nodemon": "^2.0.4", - "gulp-rev-all": "^0.8.21", - "gulp-sass": "^2.0.4", - "gulp-uglify": "^1.2.0", - "lab": "5.x.x", + "code": "^3.0.1", + "del": "^2.2.1", + "gulp": "^3.9.1", + "gulp-util": "^3.0.7", + "gulp-autoprefixer": "^3.1.0", + "gulp-jshint": "^2.0.1", + "gulp-less": "^3.1.0", + "gulp-nodemon": "^2.1.0", + "gulp-rev-all": "^0.8.24", + "gulp-sass": "^2.3.2", + "gulp-uglify": "^1.5.4", + "lab": "10.x.x", "require-dir": "^0.3.0", - "webpack": "^1.12.1" + "webpack": "^1.13.1" } } diff --git a/server.js b/server.js index 586ca158..eb6c48cc 100644 --- a/server.js +++ b/server.js @@ -1,13 +1,13 @@ 'use strict'; -var Composer = require('./index'); -var Hoek = require('hoek'); +const Composer = require('./index'); +const Hoek = require('hoek'); Composer(function(err, server) { Hoek.assert(!err, err); server.start(function() { - console.log('Server is listening'); + console.log('Server started @ ' + server.info.uri); }); - + }); From 34102e360dcd61625865679ed76afae7c8cf5779 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Sun, 17 Jul 2016 16:17:58 +0530 Subject: [PATCH 003/314] cleanup dependencies --- package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/package.json b/package.json index a3a941a8..49485459 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,6 @@ "node": ">=4.0.0" }, "dependencies": { - "bell": "^7.9.3", - "bistre": "^1.0.1", "boom": "^3.2.2", "confidence": "^3.0.1", "crumb": "^6.0.2", From 5b2b20ea2c35c1a39407dd26e8fbb6251f42836b Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Mon, 18 Jul 2016 02:11:19 +0530 Subject: [PATCH 004/314] Update to eslint --- package.json | 26 ++++++++++++++++++-------- tasks/lint.js | 13 +++++++------ tasks/nodemon.js | 2 -- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 49485459..91ecafb1 100644 --- a/package.json +++ b/package.json @@ -22,20 +22,21 @@ "bugs": { "url": "https://github.com/hks-epod/paydash/issues" }, - "engines": { "node": ">=4.0.0" }, "dependencies": { "boom": "^3.2.2", + "code": "^3.0.1", "confidence": "^3.0.1", "crumb": "^6.0.2", "d3": "^4.1.1", - "glob": "^7.5.1", + "del": "^2.2.1", + "glob": "^7.0.5", "glue": "^3.3.0", - "good": "^7.1.0", + "good": "^7.0.1", "good-file": "^6.0.1", - "googleapis": "11.0.1", + "googleapis": "^11.0.0", "handlebars": "^4.0.5", "hapi": "^13.5.0", "hapi-auth-cookie": "^6.1.1", @@ -44,29 +45,38 @@ "inert": "^4.0.1", "joi": "^9.0.1", "jquery": "^3.1.0", + "lab": "^10.9.0", "lodash": "^4.13.1", "metrics-graphics": "^2.9.0", "moment": "^2.14.1", "mysql": "^2.11.1", "request": "^2.73.0", + "require-dir": "^0.3.0", "sequelize": "^3.23.4", "vision": "^4.1.0", "visionary": "^6.0.0", + "webpack": "^1.13.1", "yar": "^7.0.2" - }, + }, "devDependencies": { + "babel-core": "^6.10.4", + "babel-loader": "^6.2.4", + "babel-preset-es2015": "^6.9.0", + "babel-preset-react": "^6.11.1", "code": "^3.0.1", "del": "^2.2.1", + "eslint-plugin-react": "^5.2.2", "gulp": "^3.9.1", - "gulp-util": "^3.0.7", "gulp-autoprefixer": "^3.1.0", - "gulp-jshint": "^2.0.1", "gulp-less": "^3.1.0", "gulp-nodemon": "^2.1.0", "gulp-rev-all": "^0.8.24", "gulp-sass": "^2.3.2", "gulp-uglify": "^1.5.4", - "lab": "10.x.x", + "gulp-util": "^3.0.7", + "lab": "^10.9.0", + "react": "^15.2.1", + "react-dom": "^15.2.1", "require-dir": "^0.3.0", "webpack": "^1.13.1" } diff --git a/tasks/lint.js b/tasks/lint.js index a68d5bf0..166c514a 100644 --- a/tasks/lint.js +++ b/tasks/lint.js @@ -1,12 +1,13 @@ 'use strict'; -var Gulp = require('gulp'); -var jshint = require('gulp-jshint'); +const Gulp = require('gulp'); +const Eslint = require('gulp-eslint'); -var paths = require('../config/assets'); +const Paths = require('../config/assets'); Gulp.task('lint', function() { - return Gulp.src(paths.get('/lint')) - .pipe(jshint()) - .pipe(jshint.reporter('default')); + return Gulp.src(Paths.get('/lint')) + .pipe(Eslint()) + .pipe(Eslint.format()) + .pipe(Eslint.failAfterError()); }); diff --git a/tasks/nodemon.js b/tasks/nodemon.js index 86d073d5..2e5d5987 100644 --- a/tasks/nodemon.js +++ b/tasks/nodemon.js @@ -1,8 +1,6 @@ 'use strict'; var Gulp = require('gulp'); var Nodemon = require('gulp-nodemon'); -var bistre = require('bistre'); - Gulp.task('nodemon', function() { var nodeArgs = []; From 08850d56ac5e2f9da17bdbb45292398833ad4b84 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Wed, 20 Jul 2016 18:30:43 +0530 Subject: [PATCH 005/314] Update gulpfile for ES2015 --- gulpfile.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index f175f66c..fa5719a3 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,12 +1,15 @@ 'use strict'; -var Gulp = require('gulp'); -var RequireDir = require('require-dir'); +const Gulp = require('gulp'); +const RequireDir = require('require-dir'); // Load Tasks + RequireDir('./tasks'); + // Build task definition + Gulp.task('dev-build', ['fonts', 'images', 'misc', 'styles', 'webpack', 'lint']); Gulp.task('prod-build', ['dev-build', 'rev']); From f1c601cc146558ca4434e1d692706e0e7194bd24 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 21 Jul 2016 17:21:14 +0530 Subject: [PATCH 006/314] Update manifest --- config/manifest.js | 187 ++++++++++++++++++++++++++++++--------------- gulpfile.js | 6 +- index.js | 6 +- server.js | 6 +- 4 files changed, 135 insertions(+), 70 deletions(-) diff --git a/config/manifest.js b/config/manifest.js index d7660c80..e66e43f8 100644 --- a/config/manifest.js +++ b/config/manifest.js @@ -1,14 +1,16 @@ 'use strict'; -var Confidence = require('confidence'); -var Config = require('./config'); +const Confidence = require('confidence'); +const Config = require('./config'); -var criteria = { - env: process.env.NODE_ENV +let internals = { + criteria: { + env: process.env.NODE_ENV + } }; -var manifest = { - $meta: 'paydash app manifest document', +internals.manifest = { + $meta: 'App manifest document', server: { connections: { router: { @@ -24,69 +26,134 @@ var manifest = { port: Config.get('/port/web'), labels: ['web'] }], - plugins: { - 'hapi-context-credentials': {}, - 'hapi-auth-cookie': {}, - './lib/flash': {}, - 'yar': { - cookieOptions: { - password: Config.get('/yarCookie/password'), - isSecure: Config.get('/yarCookie/ssl') + registrations: [ + + // Context credentials + { + plugin: 'hapi-context-credentials' + }, + // Cookie authentication + { + plugin: 'hapi-auth-cookie' + }, + // Flash Plugin + { + plugin: { + register: './lib/flash' } }, - 'good': Config.get('/good'), - 'crumb': [{ - select: ['web'], - options: { - autoGenerate: true, - skip: function(request, reply){ - return true + // Hapi cookie jar + { + plugin: { + register: 'yar', + options: { + password: Config.get('/yarCookie/password'), + isSecure: Config.get('/yarCookie/ssl') } } - }], - 'inert': {}, - 'vision': {}, - 'visionary': { - engines: { - hbs: 'handlebars' - }, - path: './app/templates', - layoutPath: './app/templates/layouts', - helpersPath: './app/templates/helpers', - partialsPath: './app/templates/partials', - layout: 'default' - }, - './lib/sequelize': Config.get('/sequelize'), - './lib/auth': Config.get('/authCookie'), - './app/routes/core': [{ - select: ['web'] - }], - './app/routes/auth': [{ - select: ['web'] - }], - './app/routes/users': [{ - select: ['web'] - }], - './app/routes/performance': [{ - select: ['web'] - }], - './app/routes/musters': [{ - select: ['web'] - }], - './app/routes/alerts': [{ - select: ['web'] - }], - './app/routes/api': { - select: ['web'] + }, + // Hapi cookie jar + { + plugin: { + register: 'yar', + options: Config.get('/yarCookie') + } + }, + // Logging + { + plugin: { + register: 'good', + options: Config.get('/good') + } + }, + // Crumb + { + plugin: { + register: 'crumb', + select: ['web'], + options: { + autoGenerate: true, + skip: function(request, reply) { + return true; + } + } + } + }, + // Static file and directory handlers + { + plugin: 'inert' + }, + + // Templates rendering support + { + plugin: 'vision' + }, + // Views loader + { + plugin: { + register: 'visionary', + options: { + engines: { + hbs: 'handlebars' + }, + path: './app/templates', + layoutPath: './app/templates/layouts', + helpersPath: './app/templates/helpers', + partialsPath: './app/templates/partials', + layout: 'default' + } + } + }, + // Sequelize + { + plugin: { + register: './lib/sequelize', + options: Config.get('/sequelize') + } + }, + // Auth + { + plugin: { + register: './lib/auth', + options: Config.get('/authCookie') + } + }, + // Core routes + { + plugin: './app/routes/core.js' + }, + // Auth routes + { + plugin: './app/routes/auth.js' + }, + // Users routes + { + plugin: './app/routes/users.js' + }, + // Performance routes + { + plugin: './app/routes/performance.js' + }, + // Musters routes + { + plugin: './app/routes/musters.js' + }, + // Alerts routes + { + plugin: './app/routes/alerts.js' + }, + // Alerts routes + { + plugin: './app/routes/api.js' } - } + ] }; -var store = new Confidence.Store(manifest); +internals.store = new Confidence.Store(internals.manifest); exports.get = function(key) { - return store.get(key, criteria); + return internals.store.get(key, internals.criteria); }; exports.meta = function(key) { - return store.meta(key, criteria); + return internals.store.meta(key, internals.criteria); }; diff --git a/gulpfile.js b/gulpfile.js index fa5719a3..e5bbf85b 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,7 +1,5 @@ -'use strict'; - -const Gulp = require('gulp'); -const RequireDir = require('require-dir'); +import Gulp from 'gulp'; +import RequireDir from 'require-dir'; // Load Tasks diff --git a/index.js b/index.js index 3c6dfb84..a9616d5f 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,9 @@ 'use strict'; -var Glue = require('glue'); -var Manifest = require('./config/manifest'); +const Glue = require('glue'); +const Manifest = require('./config/manifest'); -var composeOptions = { +const composeOptions = { relativeTo: __dirname }; diff --git a/server.js b/server.js index eb6c48cc..81e9de6d 100644 --- a/server.js +++ b/server.js @@ -3,11 +3,11 @@ const Composer = require('./index'); const Hoek = require('hoek'); -Composer(function(err, server) { +Composer((err, server) => { Hoek.assert(!err, err); - server.start(function() { - console.log('Server started @ ' + server.info.uri); + server.start(() => { + console.log(`Server started @ ${server.info.uri}`); }); }); From a620d5053e7f0b9587a74a061dfd2f726bda4ee1 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 22 Jul 2016 16:21:17 +0530 Subject: [PATCH 007/314] Update code for hapi version --- app/templates/helpers/m.js | 5 ----- assets/styles/helpers/utils.scss | 2 +- assets/styles/layout/metabar.scss | 2 +- config/manifest.js | 7 ------- gulpfile.js | 11 ++++++----- package.json | 1 + 6 files changed, 9 insertions(+), 19 deletions(-) delete mode 100644 app/templates/helpers/m.js diff --git a/app/templates/helpers/m.js b/app/templates/helpers/m.js deleted file mode 100644 index 1ef97323..00000000 --- a/app/templates/helpers/m.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; -var manifest = require('../../../public/rev-manifest.json'); -module.exports = function(filename) { - return manifest[filename]; -}; diff --git a/assets/styles/helpers/utils.scss b/assets/styles/helpers/utils.scss index 4f66b34a..c6be5c3a 100644 --- a/assets/styles/helpers/utils.scss +++ b/assets/styles/helpers/utils.scss @@ -49,5 +49,5 @@ .container:after, .pure-g:after, .u-cf { - @extend .clearfix + @extend %clearfix } diff --git a/assets/styles/layout/metabar.scss b/assets/styles/layout/metabar.scss index e29bec54..f3d3d166 100644 --- a/assets/styles/layout/metabar.scss +++ b/assets/styles/layout/metabar.scss @@ -22,7 +22,7 @@ body { width: 100%; min-height: $metabar-height; box-shadow: 0 0 1px rgba(0, 0, 0, .15); - @extend .clearfix; + @extend %clearfix; border-bottom: solid 1px rgba(255, 255, 255, 0.2) } .metabar .brand { diff --git a/config/manifest.js b/config/manifest.js index e66e43f8..ec365050 100644 --- a/config/manifest.js +++ b/config/manifest.js @@ -52,13 +52,6 @@ internals.manifest = { } } }, - // Hapi cookie jar - { - plugin: { - register: 'yar', - options: Config.get('/yarCookie') - } - }, // Logging { plugin: { diff --git a/gulpfile.js b/gulpfile.js index e5bbf85b..7a88be00 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,13 +1,14 @@ -import Gulp from 'gulp'; -import RequireDir from 'require-dir'; +'use strict'; -// Load Tasks +const Gulp = require('gulp'); +const RequireDir = require('require-dir'); -RequireDir('./tasks'); +// Load tasks +RequireDir('./tasks'); -// Build task definition +// Build task definitions Gulp.task('dev-build', ['fonts', 'images', 'misc', 'styles', 'webpack', 'lint']); Gulp.task('prod-build', ['dev-build', 'rev']); diff --git a/package.json b/package.json index 91ecafb1..01066fbc 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ "eslint-plugin-react": "^5.2.2", "gulp": "^3.9.1", "gulp-autoprefixer": "^3.1.0", + "gulp-eslint": "^3.0.1", "gulp-less": "^3.1.0", "gulp-nodemon": "^2.1.0", "gulp-rev-all": "^0.8.24", From b0d39c6cb9626c3ecb9b797a28d5c71f9b187c7f Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 22 Jul 2016 18:02:43 +0530 Subject: [PATCH 008/314] Fix upgrade bug --- app/controllers/auth/login.js | 20 ++++++-------- app/controllers/auth/logout.js | 2 +- config/manifest.js | 49 +++++++++++++++++++++------------- lib/auth.js | 33 +++++++++++------------ server.js | 7 ++--- 5 files changed, 58 insertions(+), 53 deletions(-) diff --git a/app/controllers/auth/login.js b/app/controllers/auth/login.js index 850c622e..df962588 100644 --- a/app/controllers/auth/login.js +++ b/app/controllers/auth/login.js @@ -1,12 +1,8 @@ 'use strict'; -var Boom = require('boom'); -var Joi = require('joi'); -var crypto = require('crypto'); - -var lockoutInterval = 60; // seconds -var maxAttemptsBeforeLockout = 5; - +const Boom = require('boom'); +const Joi = require('joi'); +const Crypto = require('crypto'); exports.showForm = { description: 'Returns the login page', @@ -52,7 +48,7 @@ exports.postForm = { }, failAction: function(request, reply, source, error) { // Username, passowrd minimum validation failed - request.session.flash('error', 'Invalid username or password'); + request.yar.flash('error', 'Invalid username or password'); return reply.redirect('/login'); }, }, @@ -65,14 +61,14 @@ exports.postForm = { User.findOne({ where: { username: request.payload.username, - password: crypto.createHash('md5').update(request.payload.password).digest('hex') + password: Crypto.createHash('md5').update(request.payload.password).digest('hex') }, include: [db.user_regions] }).then(function(user) { if (user) { - request.auth.session.set(user); + request.cookieAuth.set(user); if (!user.isActive) { - request.session.flash('info', 'Please check your profile details'); + request.yar.flash('info', 'Please check your profile details'); user.update({ isActive: true }).then(function() { @@ -84,7 +80,7 @@ exports.postForm = { } else { // User not fond in database - request.session.flash('error', 'Invalid username or password'); + request.yar.flash('error', 'Invalid username or password'); return reply.redirect('/login'); } }); diff --git a/app/controllers/auth/logout.js b/app/controllers/auth/logout.js index 187acdf9..d65b0d76 100644 --- a/app/controllers/auth/logout.js +++ b/app/controllers/auth/logout.js @@ -13,7 +13,7 @@ module.exports = { }, handler: function(request, reply) { - request.auth.session.clear(); + request.cookieAuth.clear(); request.session.flash('success', 'Logged out successfully'); return reply.redirect('/login'); diff --git a/config/manifest.js b/config/manifest.js index ec365050..e5493c41 100644 --- a/config/manifest.js +++ b/config/manifest.js @@ -32,46 +32,47 @@ internals.manifest = { { plugin: 'hapi-context-credentials' }, + // Cookie authentication { plugin: 'hapi-auth-cookie' }, - // Flash Plugin - { - plugin: { - register: './lib/flash' - } - }, - // Hapi cookie jar + + // Crumb { plugin: { - register: 'yar', + register: 'crumb', + select: ['web'], options: { - password: Config.get('/yarCookie/password'), - isSecure: Config.get('/yarCookie/ssl') + autoGenerate: true, + skip: function(request, reply) { + return true; + } } } }, - // Logging + + // Flash Plugin { plugin: { - register: 'good', - options: Config.get('/good') + register: './lib/flash' } }, - // Crumb + + // Hapi cookie jar { plugin: { - register: 'crumb', - select: ['web'], + register: 'yar', options: { - autoGenerate: true, - skip: function(request, reply) { - return true; + storeBlank: false, + cookieOptions: { + password: Config.get('/yarCookie/password'), + isSecure: Config.get('/yarCookie/ssl') } } } }, + // Static file and directory handlers { plugin: 'inert' @@ -81,6 +82,7 @@ internals.manifest = { { plugin: 'vision' }, + // Views loader { plugin: { @@ -97,6 +99,7 @@ internals.manifest = { } } }, + // Sequelize { plugin: { @@ -104,6 +107,7 @@ internals.manifest = { options: Config.get('/sequelize') } }, + // Auth { plugin: { @@ -111,30 +115,37 @@ internals.manifest = { options: Config.get('/authCookie') } }, + // Core routes { plugin: './app/routes/core.js' }, + // Auth routes { plugin: './app/routes/auth.js' }, + // Users routes { plugin: './app/routes/users.js' }, + // Performance routes { plugin: './app/routes/performance.js' }, + // Musters routes { plugin: './app/routes/musters.js' }, + // Alerts routes { plugin: './app/routes/alerts.js' }, + // Alerts routes { plugin: './app/routes/api.js' diff --git a/lib/auth.js b/lib/auth.js index 6d1a7c32..ec187e4a 100644 --- a/lib/auth.js +++ b/lib/auth.js @@ -1,30 +1,27 @@ 'use strict'; exports.register = function(server, options, next) { - - server.dependency(['hapi-context-credentials', 'hapi-auth-cookie', 'sequelize'], function(server, next) { - server.auth.strategy('standard', 'cookie', { - password: options.cookieSecret, // cookie secret - cookie: options.cookieName, // Cookie name - isSecure: false, // required for non-https applications - clearInvalid: true, - ttl: 24 * 60 * 60 * 1000, // Set session to 1 day - redirectTo: '/login', - // redirectOnTry: false, TODO : check out - }); - - // Blacklist all routes. - server.auth.default({ - strategy: 'standard' - }); + server.auth.strategy('standard', 'cookie', { + password: options.cookieSecret, // cookie secret + cookie: options.cookieName, // Cookie name + isSecure: false, // required for non-https applications + clearInvalid: true, + ttl: 24 * 60 * 60 * 1000, // Set session to 1 day + redirectTo: '/login', + // redirectOnTry: false, TODO : check out + }); - return next(); + // Blacklist all routes. + server.auth.default({ + strategy: 'standard' }); return next(); + }; exports.register.attributes = { - name: 'auth' + name: 'auth', + dependencies: ['hapi-auth-cookie', 'sequelize'] }; diff --git a/server.js b/server.js index 81e9de6d..ae6b99c0 100644 --- a/server.js +++ b/server.js @@ -3,11 +3,12 @@ const Composer = require('./index'); const Hoek = require('hoek'); -Composer((err, server) => { +Composer(function(err, server) { Hoek.assert(!err, err); - server.start(() => { - console.log(`Server started @ ${server.info.uri}`); + server.start(function() { + console.log('Server started @ ' + server.info.uri); }); }); + From e7ccfe8711b53a920ca0cc5d9bc0369b6577ef94 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 22 Jul 2016 18:06:57 +0530 Subject: [PATCH 009/314] Refactor code --- app/routes/alerts.js | 43 ++++++------- app/routes/api.js | 90 +++++++++++++-------------- app/routes/auth.js | 49 +++++++-------- app/routes/core.js | 128 ++++++++++++++++++-------------------- app/routes/monitor.js | 5 -- app/routes/musters.js | 5 -- app/routes/performance.js | 5 -- app/routes/users.js | 5 -- 8 files changed, 144 insertions(+), 186 deletions(-) diff --git a/app/routes/alerts.js b/app/routes/alerts.js index d49876de..37a0ac18 100644 --- a/app/routes/alerts.js +++ b/app/routes/alerts.js @@ -1,32 +1,29 @@ 'use strict'; exports.register = function(plugin, options, next) { - plugin.dependency('auth', function(plugin, next) { - var Controllers = { - alerts: { - notifications: require('../controllers/alerts/notifications') - // feedbacks: require('../controllers/alerts/feedbacks') - } - }; - plugin.route([ + var Controllers = { + alerts: { + notifications: require('../controllers/alerts/notifications') + // feedbacks: require('../controllers/alerts/feedbacks') + } + }; - // Show Notifications - { - method: 'GET', - path: '/notifications/read', - config: Controllers.alerts.notifications.showReadNotifications - }, - // Show Notifications - { - method: 'GET', - path: '/notifications/unread', - config: Controllers.alerts.notifications.showUnreadNotifications - } - ]); + plugin.route([ - next(); - }); + // Show Notifications + { + method: 'GET', + path: '/notifications/read', + config: Controllers.alerts.notifications.showReadNotifications + }, + // Show Notifications + { + method: 'GET', + path: '/notifications/unread', + config: Controllers.alerts.notifications.showUnreadNotifications + } + ]); next(); }; diff --git a/app/routes/api.js b/app/routes/api.js index 2a866c97..e49aef28 100644 --- a/app/routes/api.js +++ b/app/routes/api.js @@ -1,57 +1,51 @@ 'use strict'; exports.register = function(plugin, options, next) { - // Load plugin dependencies - plugin.dependency(['auth'], function(plugin, next) { - var Controllers = { - api: { - login: require('../controllers/api/login'), - logout: require('../controllers/api/logout'), - cards: require('../controllers/api/cards'), - profile: require('../controllers/api/profile'), - translate: require('../controllers/api/translate'), - notifications: require('../controllers/api/notifications') - } - }; + var Controllers = { + api: { + login: require('../controllers/api/login'), + logout: require('../controllers/api/logout'), + cards: require('../controllers/api/cards'), + profile: require('../controllers/api/profile'), + translate: require('../controllers/api/translate'), + notifications: require('../controllers/api/notifications') + } + }; - plugin.route([ + plugin.route([ - // Api routes - { - method: 'POST', - path: '/api/login', - config: Controllers.api.login.postForm - }, { - method: 'POST', - path: '/api/profile', - config: Controllers.api.profile.postEditProfile - }, { - method: '*', - path: '/api/logout', - config: Controllers.api.logout.postForm - }, { - method: 'GET', - path: '/api/cards', - config: Controllers.api.cards.getData - }, { - method: 'GET', - path: '/api/translate', - config: Controllers.api.translate.getData - }, { - method: 'GET', - path: '/api/notifications/unread', - config: Controllers.api.notifications.showUnreadNotifications - }, - { - method: 'GET', - path: '/api/notifications/read', - config: Controllers.api.notifications.showReadNotifications - } - ]); - - next(); - }); + // Api routes + { + method: 'POST', + path: '/api/login', + config: Controllers.api.login.postForm + }, { + method: 'POST', + path: '/api/profile', + config: Controllers.api.profile.postEditProfile + }, { + method: '*', + path: '/api/logout', + config: Controllers.api.logout.postForm + }, { + method: 'GET', + path: '/api/cards', + config: Controllers.api.cards.getData + }, { + method: 'GET', + path: '/api/translate', + config: Controllers.api.translate.getData + }, { + method: 'GET', + path: '/api/notifications/unread', + config: Controllers.api.notifications.showUnreadNotifications + }, { + method: 'GET', + path: '/api/notifications/read', + config: Controllers.api.notifications.showReadNotifications + } + ]); next(); }; diff --git a/app/routes/auth.js b/app/routes/auth.js index eeb0dea1..80395341 100644 --- a/app/routes/auth.js +++ b/app/routes/auth.js @@ -1,36 +1,31 @@ 'use strict'; exports.register = function(plugin, options, next) { - // Load plugin dependencies - plugin.dependency(['auth', 'crumb'], function(plugin, next) { - var Controllers = { - auth: { - login: require('../controllers/auth/login'), - logout: require('../controllers/auth/logout') - } - }; + var Controllers = { + auth: { + login: require('../controllers/auth/login'), + logout: require('../controllers/auth/logout') + } + }; - plugin.route([ + plugin.route([ - // auth Routes - { - method: 'GET', - path: '/login', - config: Controllers.auth.login.showForm - }, { - method: 'POST', - path: '/login', - config: Controllers.auth.login.postForm - }, { - method: '*', - path: '/logout', - config: Controllers.auth.logout - } - ]); - - next(); - }); + // auth Routes + { + method: 'GET', + path: '/login', + config: Controllers.auth.login.showForm + }, { + method: 'POST', + path: '/login', + config: Controllers.auth.login.postForm + }, { + method: '*', + path: '/logout', + config: Controllers.auth.logout + } + ]); next(); }; diff --git a/app/routes/core.js b/app/routes/core.js index fb4dce7a..ba63870b 100644 --- a/app/routes/core.js +++ b/app/routes/core.js @@ -2,79 +2,71 @@ exports.register = function(plugin, options, next) { - plugin.dependency('auth', function(plugin, next) { + var Controllers = { + core: { + pages: require('../controllers/core/pages'), + fallback: require('../controllers/core/fallback'), + static: require('../controllers/core/static') + } + }; - var Controllers = { - core: { - pages: require('../controllers/core/pages'), - fallback: require('../controllers/core/fallback'), - static: require('../controllers/core/static') - } - }; + plugin.route([ - plugin.route([ - - // Home Page - { - method: 'GET', - path: '/', - config: Controllers.core.pages.home + // Home Page + { + method: 'GET', + path: '/', + config: Controllers.core.pages.home + }, + // Assets & static Routes + { + method: 'GET', + path: '/css/{path*}', + config: { + auth: false }, - // Assets & static Routes - { - method: 'GET', - path: '/css/{path*}', - config: { - auth: false - }, - handler: Controllers.core.static.css - }, { - method: 'GET', - path: '/images/{path*}', - config: { - auth: false - }, - handler: Controllers.core.static.img - }, { - method: 'GET', - path: '/js/{path*}', - config: { - auth: false - }, - handler: Controllers.core.static.js - }, { - method: 'GET', - path: '/fonts/{path*}', - config: { - auth: false - }, - handler: Controllers.core.static.fonts - }, { - method: 'GET', - path: '/favicon.ico', - config: { - auth: false - }, - handler: Controllers.core.static.favicon - }, { - method: 'GET', - path: '/heartbeat', - config: Controllers.core.static.heartbeat + handler: Controllers.core.static.css + }, { + method: 'GET', + path: '/images/{path*}', + config: { + auth: false }, - // Fallback route - { - method: '*', - path: '/{p*}', - config: Controllers.core.fallback.notfound - } - - ]); - - next(); - }); - - + handler: Controllers.core.static.img + }, { + method: 'GET', + path: '/js/{path*}', + config: { + auth: false + }, + handler: Controllers.core.static.js + }, { + method: 'GET', + path: '/fonts/{path*}', + config: { + auth: false + }, + handler: Controllers.core.static.fonts + }, { + method: 'GET', + path: '/favicon.ico', + config: { + auth: false + }, + handler: Controllers.core.static.favicon + }, { + method: 'GET', + path: '/heartbeat', + config: Controllers.core.static.heartbeat + }, + // Fallback route + { + method: '*', + path: '/{p*}', + config: Controllers.core.fallback.notfound + } + ]); next(); }; diff --git a/app/routes/monitor.js b/app/routes/monitor.js index c3225231..f85c584d 100644 --- a/app/routes/monitor.js +++ b/app/routes/monitor.js @@ -2,8 +2,6 @@ exports.register = function(plugin, options, next) { - plugin.dependency('auth', function(plugin, next) { - var Controllers = { monitor: { user: require('../controllers/monitor/user'), @@ -58,9 +56,6 @@ exports.register = function(plugin, options, next) { } ]); - next(); - }); - next(); }; diff --git a/app/routes/musters.js b/app/routes/musters.js index a71f5f37..40217d07 100644 --- a/app/routes/musters.js +++ b/app/routes/musters.js @@ -2,8 +2,6 @@ exports.register = function(plugin, options, next) { - plugin.dependency('auth', function(plugin, next) { - var Controllers = { musters: { current: require('../controllers/musters/current-musters'), @@ -39,9 +37,6 @@ exports.register = function(plugin, options, next) { }, ]); - next(); - }); - next(); }; diff --git a/app/routes/performance.js b/app/routes/performance.js index 3efda168..0b742ee4 100644 --- a/app/routes/performance.js +++ b/app/routes/performance.js @@ -2,8 +2,6 @@ exports.register = function(plugin, options, next) { - plugin.dependency('auth', function(plugin, next) { - var Controllers = { performance: { overview: require('../controllers/performance/overview'), @@ -41,9 +39,6 @@ exports.register = function(plugin, options, next) { } ]); - next(); - }); - next(); }; diff --git a/app/routes/users.js b/app/routes/users.js index 39c9913a..b4c038b2 100644 --- a/app/routes/users.js +++ b/app/routes/users.js @@ -2,8 +2,6 @@ exports.register = function(plugin, options, next) { - plugin.dependency('auth', function(plugin, next) { - var Controllers = { settings: { profile: require('../controllers/users/settings-profile'), @@ -39,9 +37,6 @@ exports.register = function(plugin, options, next) { } ]); - next(); - }); - next(); }; From 40fc1e5de267e1c443f4b7ce0430ef3376b6e207 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Mon, 25 Jul 2016 11:51:11 +0530 Subject: [PATCH 010/314] Add api versioning --- lib/versioning.js | 107 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 lib/versioning.js diff --git a/lib/versioning.js b/lib/versioning.js new file mode 100644 index 00000000..ad5870ec --- /dev/null +++ b/lib/versioning.js @@ -0,0 +1,107 @@ +'use strict'; + +const Boom = require('boom'); +const Hoek = require('hoek'); +const Joi = require('joi'); +const MediaType = require('media-type'); + +const Package = require('./package'); + +const internals = { + optionsSchema: Joi.object({ + validVersions: Joi.array().items(Joi.number().integer()).min(1).required(), + defaultVersion: Joi.any().valid(Joi.ref('validVersions')).required(), + vendorName: Joi.string().trim().min(1).required(), + versionHeader: Joi.string().trim().min(1).default('api-version'), + passiveMode: Joi.boolean().default(false), + basePath: Joi.string().trim().min(1).default('/') + }) +}; + +const _extractVersionFromCustomHeader = function(request, options) { + + const apiVersionHeader = request.headers[options.versionHeader]; + + if (apiVersionHeader && (/^[0-9]+$/).test(apiVersionHeader)) { + return parseInt(apiVersionHeader); + } + + return null; +}; + +const _extractVersionFromAcceptHeader = function(request, options) { + + const acceptHeader = request.headers.accept; + const media = MediaType.fromString(acceptHeader); + + if (media.isValid() && (/^vnd.[a-zA-Z0-9]+\.v[0-9]+$/).test(media.subtype)) { + + if (media.subtypeFacets[1] !== options.vendorName) { + return null; + } + + const version = media.subtypeFacets[2].replace('v', ''); + + return parseInt(version); + } + + return null; +}; + +exports.register = function(server, options, next) { + + const validateOptions = internals.optionsSchema.validate(options); + + if (validateOptions.error) { + return next(validateOptions.error); + } + + //Use the validated and maybe converted values from Joi + options = validateOptions.value; + + server.ext('onRequest', (request, reply) => { + + //First check for custom header + let requestedVersion = _extractVersionFromCustomHeader(request, options); + + //If no version check accept header + if (!requestedVersion) { + requestedVersion = _extractVersionFromAcceptHeader(request, options); + } + + //If passive mode skips the rest for non versioned routes + if (options.passiveMode === true && !requestedVersion) { + return reply.continue(); + } + + //If there was a version by now check if it is valid + if (requestedVersion && !Hoek.contain(options.validVersions, requestedVersion)) { + return reply(Boom.badRequest('Invalid api-version! Valid values: ' + options.validVersions.join())); + } + + //If there was no version by now use the default version + if (!requestedVersion) { + requestedVersion = options.defaultVersion; + } + + const versionedPath = options.basePath + 'v' + requestedVersion + request.path.slice(options.basePath.length - 1); + + const route = server.match(request.method, versionedPath); + + if (route && route.path.indexOf(options.basePath + 'v' + requestedVersion + '/') === 0) { + request.setUrl(options.basePath + 'v' + requestedVersion + request.url.path.slice(options.basePath.length - 1)); //required to preserve query parameters + } + + //Set version for usage in handler + request.pre.apiVersion = requestedVersion; + + return reply.continue(); + }); + + return next(); +}; + +exports.register.attributes = { + name: Package.name, + version: Package.version +}; From 687c1d448afa3567bbe265b48f058ed968c5f9a1 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Mon, 25 Jul 2016 11:52:14 +0530 Subject: [PATCH 011/314] Update packages --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 01066fbc..e2febf4b 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "jquery": "^3.1.0", "lab": "^10.9.0", "lodash": "^4.13.1", + "media-type": "^0.3.0", "metrics-graphics": "^2.9.0", "moment": "^2.14.1", "mysql": "^2.11.1", From 2d0504b6673dd9125da45f676ac76ae8b3cfcf7d Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Mon, 25 Jul 2016 11:55:19 +0530 Subject: [PATCH 012/314] Register versioning lib --- config/manifest.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/config/manifest.js b/config/manifest.js index e5493c41..62bff0b2 100644 --- a/config/manifest.js +++ b/config/manifest.js @@ -116,6 +116,18 @@ internals.manifest = { } }, + // Versioning + { + plugin: { + register: './lib/versioning', + options: { + validVersions: [1, 2], + defaultVersion: 1, + vendorName: 'paydroid' + } + } + }, + // Core routes { plugin: './app/routes/core.js' @@ -146,7 +158,7 @@ internals.manifest = { plugin: './app/routes/alerts.js' }, - // Alerts routes + // Api routes { plugin: './app/routes/api.js' } From e5ba5542f9bf7559a91d200dd9dca7a0512a66f1 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Mon, 25 Jul 2016 12:22:29 +0530 Subject: [PATCH 013/314] Update login api --- app/controllers/api/cards.js | 370 ++++++++++++++++--------------- app/controllers/api/login.js | 2 +- app/controllers/api/logout.js | 2 +- app/controllers/api/profile.js | 1 + app/controllers/api/translate.js | 2 +- config/manifest.js | 3 +- lib/versioning.js | 5 +- 7 files changed, 193 insertions(+), 192 deletions(-) diff --git a/app/controllers/api/cards.js b/app/controllers/api/cards.js index 8ab7f04b..ac76d866 100644 --- a/app/controllers/api/cards.js +++ b/app/controllers/api/cards.js @@ -6,13 +6,15 @@ var utils = require('../../helpers/utils'); exports.getData = { - plugins: { + plugins: { 'crumb': { skip: true } }, handler: function(request, reply) { + console.log(request.pre.apiVersion); + var sequelize = request.server.plugins.sequelize.db.sequelize; var userId = request.auth.credentials.id; @@ -20,188 +22,188 @@ exports.getData = { var queryString = queries.cards(userId); // API CODE - sequelize.query(queryString, { - type: sequelize.QueryTypes.SELECT - }).then(function(rows) { - - var overviewResponse = utils.flatten(rows[0]); - - var cardsResponse = utils.flatten(rows[1]); - - var blockResponse = utils.flatten(rows[2]); - - var panchayatResponse = utils.flatten(rows[3]); - - var notificationsResponse = utils.flatten(rows[4]); - - var stateResponse = utils.flatten(rows[5]); - - var contactResponse = utils.flatten(rows[6]); - - // Parse the overview response - var current_total = overviewResponse[0].current_total; - var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].time_to_payment; - var total_transactions = overviewResponse[0].total_transactions; - - var state_code = stateResponse[0].state_code; - - // Nest the cards response and include the overview stats - var cards = d3.nest() - .key(function(d) { - var key = d.staff_id + d.block_code; - return key; - }) - .rollup(function(v) { - return { - 'name': v[0].name, - 'staff_id': v[0].staff_id, - 'designation': utils.getDesignation(v[0].task_assign,state_code), - 'mobile':v[0].mobile_no, - 'block_name':v[0].block_name, - 'current_total':v[0].current_total, - 'delayed_total':v[0].delayed_total, - 'delayed_musters': v.filter(function(d) { return d.type==='delayed_musters'; }).map(function(d) { - return [ - { - 'msr_no':d.msr_no, - 'panchayat_name':d.panchayat_name, - 'work_name':d.work_name, - 'work_code':d.work_code, - 'closure_date':d.end_date, - 'days_pending':d.days_pending - } - ]; - }), - 'current_musters': v.filter(function(d) { return d.type==='current_musters'; }).map(function(d) { - return [ - { - 'msr_no':d.msr_no, - 'panchayat_name':d.panchayat_name, - 'work_name':d.work_name, - 'work_code':d.work_code, - 'closure_date':d.end_date - } - ]; - }) - }; - }) - .entries(cardsResponse) - .map(function(d) { - return d.values; - }); - - - // Nest the block response - var blockPerformance = d3.nest() - .key(function(d) { - return d.block_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'block_name': v[0].block_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(blockResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - - // Nest the panchayat response - var panchayatPerformance = d3.nest() - .key(function(d) { - return d.panchayat_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'panchayat_code': v[0].panchayat_code, - 'panchayat_name': v[0].panchayat_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(panchayatResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; - - var data = { - 'overview': { - 'current_total':current_total, - 'delayed_total':delayed_total, - 'days_to_payment':days_to_payment, - 'total_transactions':total_transactions, - 'cards_total': cards.length - }, - 'cards': cards, - 'block_performance': blockPerformance, - 'panchayat_performance': panchayatPerformance, - 'notifications': notificationsResponse, - 'config': { - 'headers': headers, - labels: [ - 'Date', - 'Muster roll closure to muster roll entry', - 'Muster roll entry to wage list generation', - 'Wage list generation to wage list sent', - 'Wage list sent to FTO generation', - 'FTO generation to first signature', - 'First signature to second signature', - 'Second signature to processed by bank', - 'Total Transactions' - ], - }, - 'contact': { - 'phone': contactResponse[0].phone, - 'email': contactResponse[0].email, - 'subject': contactResponse[0].subject - } - }; - - reply(data); - }); + sequelize.query(queryString, { + type: sequelize.QueryTypes.SELECT + }).then(function(rows) { + + var overviewResponse = utils.flatten(rows[0]); + + var cardsResponse = utils.flatten(rows[1]); + + var blockResponse = utils.flatten(rows[2]); + + var panchayatResponse = utils.flatten(rows[3]); + + var notificationsResponse = utils.flatten(rows[4]); + + var stateResponse = utils.flatten(rows[5]); + + var contactResponse = utils.flatten(rows[6]); + + // Parse the overview response + var current_total = overviewResponse[0].current_total; + var delayed_total = overviewResponse[0].delayed_total; + var days_to_payment = overviewResponse[0].time_to_payment; + var total_transactions = overviewResponse[0].total_transactions; + + var state_code = stateResponse[0].state_code; + + // Nest the cards response and include the overview stats + var cards = d3.nest() + .key(function(d) { + var key = d.staff_id + d.block_code; + return key; + }) + .rollup(function(v) { + return { + 'name': v[0].name, + 'staff_id': v[0].staff_id, + 'designation': utils.getDesignation(v[0].task_assign, state_code), + 'mobile': v[0].mobile_no, + 'block_name': v[0].block_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'delayed_musters': v.filter(function(d) { + return d.type === 'delayed_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date, + 'days_pending': d.days_pending + }]; + }), + 'current_musters': v.filter(function(d) { + return d.type === 'current_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date + }]; + }) + }; + }) + .entries(cardsResponse) + .map(function(d) { + return d.values; + }); + + + // Nest the block response + var blockPerformance = d3.nest() + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(blockResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + + // Nest the panchayat response + var panchayatPerformance = d3.nest() + .key(function(d) { + return d.panchayat_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'panchayat_code': v[0].panchayat_code, + 'panchayat_name': v[0].panchayat_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(panchayatResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; + + var data = { + 'overview': { + 'current_total': current_total, + 'delayed_total': delayed_total, + 'days_to_payment': days_to_payment, + 'total_transactions': total_transactions, + 'cards_total': cards.length + }, + 'cards': cards, + 'block_performance': blockPerformance, + 'panchayat_performance': panchayatPerformance, + 'notifications': notificationsResponse, + 'config': { + 'headers': headers, + labels: [ + 'Date', + 'Muster roll closure to muster roll entry', + 'Muster roll entry to wage list generation', + 'Wage list generation to wage list sent', + 'Wage list sent to FTO generation', + 'FTO generation to first signature', + 'First signature to second signature', + 'Second signature to processed by bank', + 'Total Transactions' + ], + }, + 'contact': { + 'phone': contactResponse[0].phone, + 'email': contactResponse[0].email, + 'subject': contactResponse[0].subject + } + }; + + reply(data); + }); } }; diff --git a/app/controllers/api/login.js b/app/controllers/api/login.js index 1a23fb23..312633db 100644 --- a/app/controllers/api/login.js +++ b/app/controllers/api/login.js @@ -40,7 +40,7 @@ exports.postForm = { } }).then(function(user) { if (user) { - request.auth.session.set(user); + request.cookieAuth.set(user); delete user.password; return reply(user); } else { diff --git a/app/controllers/api/logout.js b/app/controllers/api/logout.js index 0943f4eb..726c550c 100644 --- a/app/controllers/api/logout.js +++ b/app/controllers/api/logout.js @@ -7,7 +7,7 @@ exports.postForm = { strategy: 'standard' }, handler: function(request, reply) { - request.auth.session.clear(); + request.cookieAuth.clear(); return reply({ "statusCode": 200, diff --git a/app/controllers/api/profile.js b/app/controllers/api/profile.js index 9e33ba0e..ad9c8380 100644 --- a/app/controllers/api/profile.js +++ b/app/controllers/api/profile.js @@ -1,6 +1,7 @@ 'use strict'; var Joi = require('joi'); +var Boom = require('boom'); exports.postEditProfile = { diff --git a/app/controllers/api/translate.js b/app/controllers/api/translate.js index 1edba949..7ab54646 100644 --- a/app/controllers/api/translate.js +++ b/app/controllers/api/translate.js @@ -16,7 +16,7 @@ exports.getData = { var res = { en_US: Translate('/app', { lang: 'en_US' }), hi: Translate('/app', { lang: 'hi' }) - } + }; reply(res); diff --git a/config/manifest.js b/config/manifest.js index 62bff0b2..37232fec 100644 --- a/config/manifest.js +++ b/config/manifest.js @@ -123,7 +123,8 @@ internals.manifest = { options: { validVersions: [1, 2], defaultVersion: 1, - vendorName: 'paydroid' + vendorName: 'paydroid', + basePath: '/api/' } } }, diff --git a/lib/versioning.js b/lib/versioning.js index ad5870ec..67c94783 100644 --- a/lib/versioning.js +++ b/lib/versioning.js @@ -5,8 +5,6 @@ const Hoek = require('hoek'); const Joi = require('joi'); const MediaType = require('media-type'); -const Package = require('./package'); - const internals = { optionsSchema: Joi.object({ validVersions: Joi.array().items(Joi.number().integer()).min(1).required(), @@ -102,6 +100,5 @@ exports.register = function(server, options, next) { }; exports.register.attributes = { - name: Package.name, - version: Package.version + name: 'api_versioning', }; From fb4ed49ae6d30a0ca6f4e1d9cd310cc68eb1aa41 Mon Sep 17 00:00:00 2001 From: edodge Date: Wed, 27 Jul 2016 22:07:24 +0530 Subject: [PATCH 014/314] Updating mobile API: add versioning and role logic. --- app/controllers/api/cards.js | 760 +++++++++++++++++++++++++-------- app/controllers/tiles/tiles.js | 1 - app/helpers/paydroid_parser.js | 14 + app/helpers/queries.js | 35 +- 4 files changed, 620 insertions(+), 190 deletions(-) create mode 100644 app/helpers/paydroid_parser.js diff --git a/app/controllers/api/cards.js b/app/controllers/api/cards.js index ac76d866..4d4bf850 100644 --- a/app/controllers/api/cards.js +++ b/app/controllers/api/cards.js @@ -13,197 +13,595 @@ exports.getData = { }, handler: function(request, reply) { - console.log(request.pre.apiVersion); - var sequelize = request.server.plugins.sequelize.db.sequelize; var userId = request.auth.credentials.id; + var role = request.auth.credentials.role; + var version = request.pre.apiVersion; - var queryString = queries.cards(userId); + var queryString = queries.cards(userId,role,version); // API CODE sequelize.query(queryString, { type: sequelize.QueryTypes.SELECT }).then(function(rows) { - var overviewResponse = utils.flatten(rows[0]); - - var cardsResponse = utils.flatten(rows[1]); - - var blockResponse = utils.flatten(rows[2]); - - var panchayatResponse = utils.flatten(rows[3]); - - var notificationsResponse = utils.flatten(rows[4]); - - var stateResponse = utils.flatten(rows[5]); - - var contactResponse = utils.flatten(rows[6]); - - // Parse the overview response - var current_total = overviewResponse[0].current_total; - var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].time_to_payment; - var total_transactions = overviewResponse[0].total_transactions; - - var state_code = stateResponse[0].state_code; - - // Nest the cards response and include the overview stats - var cards = d3.nest() - .key(function(d) { - var key = d.staff_id + d.block_code; - return key; - }) - .rollup(function(v) { - return { - 'name': v[0].name, - 'staff_id': v[0].staff_id, - 'designation': utils.getDesignation(v[0].task_assign, state_code), - 'mobile': v[0].mobile_no, - 'block_name': v[0].block_name, - 'current_total': v[0].current_total, - 'delayed_total': v[0].delayed_total, - 'delayed_musters': v.filter(function(d) { - return d.type === 'delayed_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date, - 'days_pending': d.days_pending - }]; - }), - 'current_musters': v.filter(function(d) { - return d.type === 'current_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date - }]; - }) - }; - }) - .entries(cardsResponse) - .map(function(d) { - return d.values; - }); - - - // Nest the block response - var blockPerformance = d3.nest() - .key(function(d) { - return d.block_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'block_name': v[0].block_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(blockResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - - // Nest the panchayat response - var panchayatPerformance = d3.nest() - .key(function(d) { - return d.panchayat_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'panchayat_code': v[0].panchayat_code, - 'panchayat_name': v[0].panchayat_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(panchayatResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; - - var data = { - 'overview': { - 'current_total': current_total, - 'delayed_total': delayed_total, - 'days_to_payment': days_to_payment, - 'total_transactions': total_transactions, - 'cards_total': cards.length - }, - 'cards': cards, - 'block_performance': blockPerformance, - 'panchayat_performance': panchayatPerformance, - 'notifications': notificationsResponse, - 'config': { - 'headers': headers, - labels: [ - 'Date', - 'Muster roll closure to muster roll entry', - 'Muster roll entry to wage list generation', - 'Wage list generation to wage list sent', - 'Wage list sent to FTO generation', - 'FTO generation to first signature', - 'First signature to second signature', - 'Second signature to processed by bank', - 'Total Transactions' - ], - }, - 'contact': { - 'phone': contactResponse[0].phone, - 'email': contactResponse[0].email, - 'subject': contactResponse[0].subject - } - }; - - reply(data); + if (version===1) { + + var overviewResponse = utils.flatten(rows[0]); + + var cardsResponse = utils.flatten(rows[1]); + + var blockResponse = utils.flatten(rows[2]); + + var panchayatResponse = utils.flatten(rows[3]); + + var notificationsResponse = utils.flatten(rows[4]); + + var stateResponse = utils.flatten(rows[5]); + + var contactResponse = utils.flatten(rows[6]); + + // Parse the overview response + var current_total = overviewResponse[0].current_total; + var delayed_total = overviewResponse[0].delayed_total; + var days_to_payment = overviewResponse[0].time_to_payment; + var total_transactions = overviewResponse[0].total_transactions; + + var state_code = stateResponse[0].state_code; + + // Nest the cards response and include the overview stats + var cards = d3.nest() + .key(function(d) { + var key = d.staff_id; + return key; + }) + .rollup(function(v) { + return { + 'name': v[0].name, + 'staff_id': v[0].staff_id, + 'designation': utils.getDesignation(v[0].task_assign, state_code), + 'mobile': v[0].mobile_no, + 'block_name': v[0].block_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'delayed_musters': v.filter(function(d) { + return d.type === 'delayed_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date, + 'days_pending': d.days_pending + }]; + }), + 'current_musters': v.filter(function(d) { + return d.type === 'current_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date + }]; + }) + }; + }) + .entries(cardsResponse) + .map(function(d) { + return d.values; + }); + + + // Nest the block response + var blockPerformance = d3.nest() + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(blockResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + + // Nest the panchayat response + var panchayatPerformance = d3.nest() + .key(function(d) { + return d.panchayat_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'panchayat_code': v[0].panchayat_code, + 'panchayat_name': v[0].panchayat_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(panchayatResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; + + var data = { + 'overview': { + 'current_total': current_total, + 'delayed_total': delayed_total, + 'days_to_payment': days_to_payment, + 'total_transactions': total_transactions, + 'cards_total': cards.length + }, + 'cards': cards, + 'block_performance': blockPerformance, + 'panchayat_performance': panchayatPerformance, + 'notifications': notificationsResponse, + 'config': { + 'headers': headers, + labels: [ + 'Date', + 'Muster roll closure to muster roll entry', + 'Muster roll entry to wage list generation', + 'Wage list generation to wage list sent', + 'Wage list sent to FTO generation', + 'FTO generation to first signature', + 'First signature to second signature', + 'Second signature to processed by bank', + 'Total Transactions' + ], + }, + 'contact': { + 'phone': contactResponse[0].phone, + 'email': contactResponse[0].email, + 'subject': contactResponse[0].subject + } + }; + + reply(data); + } else if (version===2) { + + if (role==='block') { + + var overviewResponse = utils.flatten(rows[0]); + + var cardsResponse = utils.flatten(rows[1]); + + var blockResponse = utils.flatten(rows[2]); + + var panchayatResponse = utils.flatten(rows[3]); + + var stateResponse = utils.flatten(rows[4]); + + var contactResponse = utils.flatten(rows[5]); + + // Parse the overview response + var current_total = overviewResponse[0].current_total; + var delayed_total = overviewResponse[0].delayed_total; + var days_to_payment = overviewResponse[0].time_to_payment; + + var state_code = stateResponse[0].state_code; + + // Nest the cards response and include the overview stats + var cards = d3.nest() + .key(function(d) { + var key = d.staff_id + d.block_code; + return key; + }) + .rollup(function(v) { + return { + 'name': v[0].name, + 'staff_id': v[0].staff_id, + 'designation': utils.getDesignation(v[0].task_assign, state_code), + 'mobile': v[0].mobile_no, + 'block_name': v[0].block_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'delayed_musters': v.filter(function(d) { + return d.type === 'delayed_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date, + 'days_pending': d.days_pending + }]; + }), + 'current_musters': v.filter(function(d) { + return d.type === 'current_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date + }]; + }) + }; + }) + .entries(cardsResponse) + .map(function(d) { + return d.values; + }); + + + // Nest the block response + var blockPerformance = d3.nest() + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(blockResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + + // Nest the panchayat response + var panchayatPerformance = d3.nest() + .key(function(d) { + return d.panchayat_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'panchayat_code': v[0].panchayat_code, + 'panchayat_name': v[0].panchayat_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(panchayatResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; + + var data = { + 'overview': { + 'current_total': current_total, + 'delayed_total': delayed_total, + 'days_to_payment': days_to_payment, + 'cards_total': cards.length + }, + 'cards': cards, + 'block_performance': blockPerformance, + 'panchayat_performance': panchayatPerformance, + 'config': { + 'headers': headers, + labels: [ + 'Date', + 'Muster roll closure to muster roll entry', + 'Muster roll entry to wage list generation', + 'Wage list generation to wage list sent', + 'Wage list sent to FTO generation', + 'FTO generation to first signature', + 'First signature to second signature', + 'Second signature to processed by bank', + 'Total Transactions' + ], + }, + 'contact': { + 'phone': contactResponse[0].phone, + 'email': contactResponse[0].email, + 'subject': contactResponse[0].subject + } + }; + + reply(data); + + } else if (role==='district') { + + var overviewResponse = utils.flatten(rows[0]); + + var cardsResponse = utils.flatten(rows[1]); + + var districtResponse = utils.flatten(rows[2]); + + var blockResponse = utils.flatten(rows[3]); + + var panchayatResponse = utils.flatten(rows[4]); + + var stateResponse = utils.flatten(rows[5]); + + var contactResponse = utils.flatten(rows[6]); + + // Parse the overview response + var current_total = overviewResponse[0].current_total; + var delayed_total = overviewResponse[0].delayed_total; + var days_to_payment = overviewResponse[0].time_to_payment; + + var state_code = stateResponse[0].state_code; + + // Nest the cards response and include the overview stats + var cards = d3.nest() + .key(function(d) { + var key = d.staff_id + d.district_code; + return key; + }) + .rollup(function(v) { + return { + 'name': v[0].name, + 'staff_id': v[0].staff_id, + 'designation': utils.getDesignation(v[0].task_assign, state_code), + 'mobile': v[0].mobile_no, + 'district_name': v[0].block_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'delayed_musters': v.filter(function(d) { + return d.type === 'delayed_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date, + 'days_pending': d.days_pending + }]; + }), + 'current_musters': v.filter(function(d) { + return d.type === 'current_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date + }]; + }) + }; + }) + .entries(cardsResponse) + .map(function(d) { + return d.values; + }); + + // Nest the district response + var districtPerformance = d3.nest() + .key(function(d) { + return d.district_code; + }) + .rollup(function(v) { + return { + 'district_code': v[0].block_code, + 'district_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(districtResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + + // Nest the block response + var blockPerformance = d3.nest() + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(blockResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + + // Nest the panchayat response + var panchayatPerformance = d3.nest() + .key(function(d) { + return d.panchayat_code; + }) + .rollup(function(v) { + return { + 'district_code': v[0].district_code, + 'block_code': v[0].block_code, + 'panchayat_code': v[0].panchayat_code, + 'panchayat_name': v[0].panchayat_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(panchayatResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; + + var data = { + 'overview': { + 'current_total': current_total, + 'delayed_total': delayed_total, + 'days_to_payment': days_to_payment, + 'cards_total': cards.length + }, + 'cards': cards, + 'block_performance': blockPerformance, + 'panchayat_performance': panchayatPerformance, + 'config': { + 'headers': headers, + labels: [ + 'Date', + 'Muster roll closure to muster roll entry', + 'Muster roll entry to wage list generation', + 'Wage list generation to wage list sent', + 'Wage list sent to FTO generation', + 'FTO generation to first signature', + 'First signature to second signature', + 'Second signature to processed by bank', + 'Total Transactions' + ], + }, + 'contact': { + 'phone': contactResponse[0].phone, + 'email': contactResponse[0].email, + 'subject': contactResponse[0].subject + } + }; + + reply(data); + + } + } + }); } }; diff --git a/app/controllers/tiles/tiles.js b/app/controllers/tiles/tiles.js index 151d7511..1d072b58 100644 --- a/app/controllers/tiles/tiles.js +++ b/app/controllers/tiles/tiles.js @@ -89,7 +89,6 @@ exports.getData = { 'current_total':current_total, 'delayed_total':delayed_total, 'days_to_payment':days_to_payment, - 'total_transactions':total_transactions, 'tiles_total': tiles.length }, 'tiles': tiles, diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js new file mode 100644 index 00000000..53f192ba --- /dev/null +++ b/app/helpers/paydroid_parser.js @@ -0,0 +1,14 @@ +'use strict'; + +var Utils = require('./utils'); + + +exports.block = function(rows) { + + +} + +exports.district = function(rows) { + + +} diff --git a/app/helpers/queries.js b/app/helpers/queries.js index 2ec155f9..5fd6480c 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -71,12 +71,31 @@ exports.delayed_musters = function(BLOCK_CODE) { "SELECT IFNULL(a.total_panchayat_count,0) AS total_panchayat_count, IFNULL(b.ta_panchayat_count,0) AS ta_panchayat_count, IFNULL(c.grs_panchayat_count,0) AS grs_panchayat_count FROM (SELECT block_code, count(*) AS total_panchayat_count FROM panchayats WHERE block_code = '" + BLOCK_CODE + "') a LEFT JOIN (SELECT block_code, count(*) AS ta_panchayat_count FROM employees WHERE task_assign = 'TA' AND block_code = '" + BLOCK_CODE + "') b ON a.block_code = b.block_code LEFT JOIN (SELECT block_code, count(*) AS grs_panchayat_count FROM employees WHERE task_assign = 'GRS' AND block_code = '" + BLOCK_CODE + "') c ON a.block_code = c.block_code;"; }; -exports.cards = function(USER_ID) { - return "SELECT a.current_total, b.delayed_total, c.time_to_payment, c.total_transactions FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment, IFNULL(SUM(total_transactions),0) AS total_transactions, 1 AS merge FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + - "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + - "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + - "SELECT block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY panchayat_code, date;" + - "SELECT * FROM notifications WHERE user_id = '"+USER_ID+"';" + - "SELECT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + - "SELECT * FROM contact;"; +exports.cards = function(USER_ID,ROLE,VERSION) { + if (VERSION===1) { + return "SELECT a.current_total, b.delayed_total, c.time_to_payment, c.total_transactions FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment, IFNULL(SUM(total_transactions),0) AS total_transactions, 1 AS merge FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + + "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + + "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + + "SELECT block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY panchayat_code, date;" + + "SELECT * FROM notifications WHERE user_id = '"+USER_ID+"';" + + "SELECT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + + "SELECT * FROM contact;"; + } else if (VERSION===2) { + if (ROLE==='block') { + return "SELECT a.current_total, b.delayed_total, c.time_to_payment FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment, 1 AS merge FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + + "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + + "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + + "SELECT block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY panchayat_code, date;" + + "SELECT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + + "SELECT * FROM contact;"; + } else if (ROLE=='district') { + return "SELECT a.current_total, b.delayed_total, c.time_to_payment FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment, 1 AS merge FROM district_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + + "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.username, j.title, j.firstname, j.lastname, j.designation, j.mobile, b.time_to_payment, c.current_total, d.delayed_total, e.t2_total, e.t2_avg, f.t5_total, f.t5_avg, g.t6_total, g.t6_avg, h.t7_total, h.t7_avg, i.t8_total, i.t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, AVG(datediff(CURDATE(), a.end_date) - 2) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, AVG(datediff(CURDATE(), a.end_date) - 5) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, AVG(datediff(CURDATE(), a.end_date) - 6) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, AVG(datediff(CURDATE(), a.end_date) - 7) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, AVG(datediff(CURDATE(), a.end_date) - 8) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;" + + "SELECT district_code, district_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM district_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY district_code, date;" + + "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + + "SELECT district_code, block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY panchayat_code, date;" + + "SELECT state_code FROM districts WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + + "SELECT * FROM contact;"; + } + } }; From 2bdf26cc0bd97e90de8817cf06f4bc7b5b0a6673 Mon Sep 17 00:00:00 2001 From: edodge Date: Thu, 28 Jul 2016 21:33:13 +0530 Subject: [PATCH 015/314] Refactoring PayDash API code --- app/controllers/api/cards.js | 576 +-------------------------------- app/helpers/paydroid_parser.js | 574 +++++++++++++++++++++++++++++++- app/helpers/queries.js | 18 +- 3 files changed, 585 insertions(+), 583 deletions(-) diff --git a/app/controllers/api/cards.js b/app/controllers/api/cards.js index 4d4bf850..65c5fcf4 100644 --- a/app/controllers/api/cards.js +++ b/app/controllers/api/cards.js @@ -1,9 +1,7 @@ 'use strict'; -var d3 = require('d3'); var queries = require('../../helpers/queries'); -var utils = require('../../helpers/utils'); - +var parser = require('../../helpers/paydroid_parser'); exports.getData = { plugins: { @@ -28,579 +26,15 @@ exports.getData = { if (version===1) { - var overviewResponse = utils.flatten(rows[0]); - - var cardsResponse = utils.flatten(rows[1]); - - var blockResponse = utils.flatten(rows[2]); - - var panchayatResponse = utils.flatten(rows[3]); - - var notificationsResponse = utils.flatten(rows[4]); - - var stateResponse = utils.flatten(rows[5]); - - var contactResponse = utils.flatten(rows[6]); - - // Parse the overview response - var current_total = overviewResponse[0].current_total; - var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].time_to_payment; - var total_transactions = overviewResponse[0].total_transactions; - - var state_code = stateResponse[0].state_code; - - // Nest the cards response and include the overview stats - var cards = d3.nest() - .key(function(d) { - var key = d.staff_id; - return key; - }) - .rollup(function(v) { - return { - 'name': v[0].name, - 'staff_id': v[0].staff_id, - 'designation': utils.getDesignation(v[0].task_assign, state_code), - 'mobile': v[0].mobile_no, - 'block_name': v[0].block_name, - 'current_total': v[0].current_total, - 'delayed_total': v[0].delayed_total, - 'delayed_musters': v.filter(function(d) { - return d.type === 'delayed_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date, - 'days_pending': d.days_pending - }]; - }), - 'current_musters': v.filter(function(d) { - return d.type === 'current_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date - }]; - }) - }; - }) - .entries(cardsResponse) - .map(function(d) { - return d.values; - }); - - - // Nest the block response - var blockPerformance = d3.nest() - .key(function(d) { - return d.block_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'block_name': v[0].block_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(blockResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - + var data = parser.v1(rows); - // Nest the panchayat response - var panchayatPerformance = d3.nest() - .key(function(d) { - return d.panchayat_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'panchayat_code': v[0].panchayat_code, - 'panchayat_name': v[0].panchayat_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(panchayatResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; - - var data = { - 'overview': { - 'current_total': current_total, - 'delayed_total': delayed_total, - 'days_to_payment': days_to_payment, - 'total_transactions': total_transactions, - 'cards_total': cards.length - }, - 'cards': cards, - 'block_performance': blockPerformance, - 'panchayat_performance': panchayatPerformance, - 'notifications': notificationsResponse, - 'config': { - 'headers': headers, - labels: [ - 'Date', - 'Muster roll closure to muster roll entry', - 'Muster roll entry to wage list generation', - 'Wage list generation to wage list sent', - 'Wage list sent to FTO generation', - 'FTO generation to first signature', - 'First signature to second signature', - 'Second signature to processed by bank', - 'Total Transactions' - ], - }, - 'contact': { - 'phone': contactResponse[0].phone, - 'email': contactResponse[0].email, - 'subject': contactResponse[0].subject - } - }; - - reply(data); } else if (version===2) { - if (role==='block') { - - var overviewResponse = utils.flatten(rows[0]); - - var cardsResponse = utils.flatten(rows[1]); - - var blockResponse = utils.flatten(rows[2]); - - var panchayatResponse = utils.flatten(rows[3]); - - var stateResponse = utils.flatten(rows[4]); - - var contactResponse = utils.flatten(rows[5]); - - // Parse the overview response - var current_total = overviewResponse[0].current_total; - var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].time_to_payment; - - var state_code = stateResponse[0].state_code; - - // Nest the cards response and include the overview stats - var cards = d3.nest() - .key(function(d) { - var key = d.staff_id + d.block_code; - return key; - }) - .rollup(function(v) { - return { - 'name': v[0].name, - 'staff_id': v[0].staff_id, - 'designation': utils.getDesignation(v[0].task_assign, state_code), - 'mobile': v[0].mobile_no, - 'block_name': v[0].block_name, - 'current_total': v[0].current_total, - 'delayed_total': v[0].delayed_total, - 'delayed_musters': v.filter(function(d) { - return d.type === 'delayed_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date, - 'days_pending': d.days_pending - }]; - }), - 'current_musters': v.filter(function(d) { - return d.type === 'current_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date - }]; - }) - }; - }) - .entries(cardsResponse) - .map(function(d) { - return d.values; - }); - + var data = parser.v2(rows,role); - // Nest the block response - var blockPerformance = d3.nest() - .key(function(d) { - return d.block_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'block_name': v[0].block_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(blockResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - - // Nest the panchayat response - var panchayatPerformance = d3.nest() - .key(function(d) { - return d.panchayat_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'panchayat_code': v[0].panchayat_code, - 'panchayat_name': v[0].panchayat_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(panchayatResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; - - var data = { - 'overview': { - 'current_total': current_total, - 'delayed_total': delayed_total, - 'days_to_payment': days_to_payment, - 'cards_total': cards.length - }, - 'cards': cards, - 'block_performance': blockPerformance, - 'panchayat_performance': panchayatPerformance, - 'config': { - 'headers': headers, - labels: [ - 'Date', - 'Muster roll closure to muster roll entry', - 'Muster roll entry to wage list generation', - 'Wage list generation to wage list sent', - 'Wage list sent to FTO generation', - 'FTO generation to first signature', - 'First signature to second signature', - 'Second signature to processed by bank', - 'Total Transactions' - ], - }, - 'contact': { - 'phone': contactResponse[0].phone, - 'email': contactResponse[0].email, - 'subject': contactResponse[0].subject - } - }; - - reply(data); - - } else if (role==='district') { - - var overviewResponse = utils.flatten(rows[0]); - - var cardsResponse = utils.flatten(rows[1]); - - var districtResponse = utils.flatten(rows[2]); - - var blockResponse = utils.flatten(rows[3]); - - var panchayatResponse = utils.flatten(rows[4]); - - var stateResponse = utils.flatten(rows[5]); - - var contactResponse = utils.flatten(rows[6]); - - // Parse the overview response - var current_total = overviewResponse[0].current_total; - var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].time_to_payment; - - var state_code = stateResponse[0].state_code; - - // Nest the cards response and include the overview stats - var cards = d3.nest() - .key(function(d) { - var key = d.staff_id + d.district_code; - return key; - }) - .rollup(function(v) { - return { - 'name': v[0].name, - 'staff_id': v[0].staff_id, - 'designation': utils.getDesignation(v[0].task_assign, state_code), - 'mobile': v[0].mobile_no, - 'district_name': v[0].block_name, - 'current_total': v[0].current_total, - 'delayed_total': v[0].delayed_total, - 'delayed_musters': v.filter(function(d) { - return d.type === 'delayed_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date, - 'days_pending': d.days_pending - }]; - }), - 'current_musters': v.filter(function(d) { - return d.type === 'current_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date - }]; - }) - }; - }) - .entries(cardsResponse) - .map(function(d) { - return d.values; - }); - - // Nest the district response - var districtPerformance = d3.nest() - .key(function(d) { - return d.district_code; - }) - .rollup(function(v) { - return { - 'district_code': v[0].block_code, - 'district_name': v[0].block_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(districtResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - - // Nest the block response - var blockPerformance = d3.nest() - .key(function(d) { - return d.block_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'block_name': v[0].block_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(blockResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - - // Nest the panchayat response - var panchayatPerformance = d3.nest() - .key(function(d) { - return d.panchayat_code; - }) - .rollup(function(v) { - return { - 'district_code': v[0].district_code, - 'block_code': v[0].block_code, - 'panchayat_code': v[0].panchayat_code, - 'panchayat_name': v[0].panchayat_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(panchayatResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; - - var data = { - 'overview': { - 'current_total': current_total, - 'delayed_total': delayed_total, - 'days_to_payment': days_to_payment, - 'cards_total': cards.length - }, - 'cards': cards, - 'block_performance': blockPerformance, - 'panchayat_performance': panchayatPerformance, - 'config': { - 'headers': headers, - labels: [ - 'Date', - 'Muster roll closure to muster roll entry', - 'Muster roll entry to wage list generation', - 'Wage list generation to wage list sent', - 'Wage list sent to FTO generation', - 'FTO generation to first signature', - 'First signature to second signature', - 'Second signature to processed by bank', - 'Total Transactions' - ], - }, - 'contact': { - 'phone': contactResponse[0].phone, - 'email': contactResponse[0].email, - 'subject': contactResponse[0].subject - } - }; - - reply(data); - - } } + + reply(data); }); } diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index 53f192ba..bfbc8a07 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -1,14 +1,582 @@ 'use strict'; -var Utils = require('./utils'); +var d3 = require('d3'); +var utils = require('./utils'); +exports.v1 = function(rows) { -exports.block = function(rows) { + var overviewResponse = d3.values(rows[0]); + var cardsResponse = d3.values(rows[1]); + var blockResponse = d3.values(rows[2]); + + var panchayatResponse = d3.values(rows[3]); + + var notificationsResponse = d3.values(rows[4]); + + var stateResponse = d3.values(rows[5]); + + var contactResponse = d3.values(rows[6]); + + // Parse the overview response + var current_total = overviewResponse[0].current_total; + var delayed_total = overviewResponse[0].delayed_total; + var days_to_payment = overviewResponse[0].time_to_payment; + var total_transactions = overviewResponse[0].total_transactions; + + var state_code = stateResponse[0].state_code; + + // Nest the cards response and include the overview stats + var cards = d3.nest() + .key(function(d) { + return d.staff_id; + }) + .rollup(function(v) { + return { + 'name': v[0].name, + 'staff_id': v[0].staff_id, + 'designation': utils.getDesignation(v[0].task_assign, state_code), + 'mobile': v[0].mobile_no, + 'block_name': v[0].block_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'delayed_musters': v.filter(function(d) { + return d.type === 'delayed_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date, + 'days_pending': d.days_pending + }]; + }), + 'current_musters': v.filter(function(d) { + return d.type === 'current_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date + }]; + }) + }; + }) + .entries(cardsResponse) + .map(function(d) { + return d.value; + }); + + // Nest the block response + var blockPerformance = d3.nest() + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(blockResponse) + .map(function(d) { + return d.value; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + + // Nest the panchayat response + var panchayatPerformance = d3.nest() + .key(function(d) { + return d.panchayat_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'panchayat_code': v[0].panchayat_code, + 'panchayat_name': v[0].panchayat_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(panchayatResponse) + .map(function(d) { + return d.value; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; + + var data = { + 'overview': { + 'current_total': current_total, + 'delayed_total': delayed_total, + 'days_to_payment': days_to_payment, + 'total_transactions': total_transactions, + 'cards_total': cards.length + }, + 'cards': cards, + 'block_performance': blockPerformance, + 'panchayat_performance': panchayatPerformance, + 'notifications': notificationsResponse, + 'config': { + 'headers': headers, + labels: [ + 'Date', + 'Muster roll closure to muster roll entry', + 'Muster roll entry to wage list generation', + 'Wage list generation to wage list sent', + 'Wage list sent to FTO generation', + 'FTO generation to first signature', + 'First signature to second signature', + 'Second signature to processed by bank', + 'Total Transactions' + ], + }, + 'contact': { + 'phone': contactResponse[0].phone, + 'email': contactResponse[0].email, + 'subject': contactResponse[0].subject + } + }; + + return data; } -exports.district = function(rows) { +exports.v2 = function(rows, role) { + + function parse_block(rows) { + + var overviewResponse = d3.values(rows[0]); + + var cardsResponse = d3.values(rows[1]); + + var blockResponse = d3.values(rows[2]); + + var panchayatResponse = d3.values(rows[3]); + + var stateResponse = d3.values(rows[4]); + + var contactResponse = d3.values(rows[5]); + + // Parse the overview response + var current_total = overviewResponse[0].current_total; + var delayed_total = overviewResponse[0].delayed_total; + var days_to_payment = overviewResponse[0].time_to_payment; + + var state_code = stateResponse[0].state_code; + + // Nest the cards response and include the overview stats + var cards = d3.nest() + .key(function(d) { + var key = d.staff_id + d.block_code; + return key; + }) + .rollup(function(v) { + return { + 'name': v[0].name, + 'staff_id': v[0].staff_id, + 'designation': utils.getDesignation(v[0].task_assign, state_code), + 'mobile': v[0].mobile_no, + 'block_name': v[0].block_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'delayed_musters': v.filter(function(d) { + return d.type === 'delayed_musters'; + }).map(function(d) { + return { + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date, + 'days_pending': d.days_pending + }; + }), + 'current_musters': v.filter(function(d) { + return d.type === 'current_musters'; + }).map(function(d) { + return { + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date + }; + }) + }; + }) + .entries(cardsResponse) + .map(function(d) { + return d.value; + }); + + + // Nest the block response + var blockPerformance = d3.nest() + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(blockResponse) + .map(function(d) { + return d.value; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + + // Nest the panchayat response + var panchayatPerformance = d3.nest() + .key(function(d) { + return d.panchayat_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'panchayat_code': v[0].panchayat_code, + 'panchayat_name': v[0].panchayat_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(panchayatResponse) + .map(function(d) { + return d.value; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; + + var data = { + 'overview': { + 'current_total': current_total, + 'delayed_total': delayed_total, + 'days_to_payment': days_to_payment, + 'cards_total': cards.length + }, + 'cards': cards, + 'block_performance': blockPerformance, + 'panchayat_performance': panchayatPerformance, + 'config': { + 'headers': headers, + labels: [ + 'Date', + 'Muster roll closure to muster roll entry', + 'Muster roll entry to wage list generation', + 'Wage list generation to wage list sent', + 'Wage list sent to FTO generation', + 'FTO generation to first signature', + 'First signature to second signature', + 'Second signature to processed by bank', + 'Total Transactions' + ], + }, + 'contact': { + 'phone': contactResponse[0].phone, + 'email': contactResponse[0].email, + 'subject': contactResponse[0].subject + } + }; + + return data; + } + + function parse_district(rows) { + + var overviewResponse = d3.values(rows[0]); + + var cardsResponse = d3.values(rows[1]); + + var districtResponse = d3.values(rows[2]); + + var blockResponse = d3.values(rows[3]); + + var panchayatResponse = d3.values(rows[4]); + + var stateResponse = d3.values(rows[5]); + + var contactResponse = d3.values(rows[6]); + + // Parse the overview response + var current_total = overviewResponse[0].current_total; + var delayed_total = overviewResponse[0].delayed_total; + var days_to_payment = overviewResponse[0].time_to_payment; + + var state_code = stateResponse[0].state_code; + + // Nest the cards response and include the overview stats + var cards = d3.nest() + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'officers': v.map(function(d) { + return { + name: d.id == null ? 'No Data' : d.firstname + ' ' + d.lastname, + designation: d.designation, + mobile: d.mobile + }; + }), + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 't2_total': v[0].t2_total, + 't2_avg': v[0].t2_avg, + 't5_total': v[0].t5_total, + 't5_avg': v[0].t5_avg, + 't6_total': v[0].t6_total, + 't6_avg': v[0].t6_avg, + 't7_total': v[0].t7_total, + 't7_avg': v[0].t7_avg, + 't8_total': v[0].t8_total, + 't8_avg': v[0].t8_avg + }; + }) + .entries(cardsResponse) + .map(function(d) { + return d.value; + }); + + // Nest the district response + var districtPerformance = d3.nest() + .key(function(d) { + return d.district_code; + }) + .rollup(function(v) { + return { + 'district_code': v[0].block_code, + 'district_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(districtResponse) + .map(function(d) { + return d.value; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + + // Nest the block response + var blockPerformance = d3.nest() + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(blockResponse) + .map(function(d) { + return d.value; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + + // Nest the panchayat response + var panchayatPerformance = d3.nest() + .key(function(d) { + return d.panchayat_code; + }) + .rollup(function(v) { + return { + 'district_code': v[0].district_code, + 'block_code': v[0].block_code, + 'panchayat_code': v[0].panchayat_code, + 'panchayat_name': v[0].panchayat_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(panchayatResponse) + .map(function(d) { + return d.value; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; + + var data = { + 'overview': { + 'current_total': current_total, + 'delayed_total': delayed_total, + 'days_to_payment': days_to_payment, + 'cards_total': cards.length + }, + 'cards': cards, + 'block_performance': blockPerformance, + 'panchayat_performance': panchayatPerformance, + 'config': { + 'headers': headers, + labels: [ + 'Date', + 'Muster roll closure to muster roll entry', + 'Muster roll entry to wage list generation', + 'Wage list generation to wage list sent', + 'Wage list sent to FTO generation', + 'FTO generation to first signature', + 'First signature to second signature', + 'Second signature to processed by bank', + 'Total Transactions' + ], + }, + 'contact': { + 'phone': contactResponse[0].phone, + 'email': contactResponse[0].email, + 'subject': contactResponse[0].subject + } + }; + + return data; + } + + if (role==='block') { + + var data = parse_block(rows); + + } else if (role==='district') { + + var data = parse_district(rows); + } + return data; } diff --git a/app/helpers/queries.js b/app/helpers/queries.js index 5fd6480c..ae247536 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -75,8 +75,8 @@ exports.cards = function(USER_ID,ROLE,VERSION) { if (VERSION===1) { return "SELECT a.current_total, b.delayed_total, c.time_to_payment, c.total_transactions FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment, IFNULL(SUM(total_transactions),0) AS total_transactions, 1 AS merge FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + - "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + - "SELECT block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY panchayat_code, date;" + + "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + + "SELECT block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY panchayat_code, date;" + "SELECT * FROM notifications WHERE user_id = '"+USER_ID+"';" + "SELECT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + "SELECT * FROM contact;"; @@ -84,16 +84,16 @@ exports.cards = function(USER_ID,ROLE,VERSION) { if (ROLE==='block') { return "SELECT a.current_total, b.delayed_total, c.time_to_payment FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment, 1 AS merge FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + - "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + - "SELECT block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY panchayat_code, date;" + + "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + + "SELECT block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY panchayat_code, date;" + "SELECT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + "SELECT * FROM contact;"; } else if (ROLE=='district') { - return "SELECT a.current_total, b.delayed_total, c.time_to_payment FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment, 1 AS merge FROM district_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + - "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.username, j.title, j.firstname, j.lastname, j.designation, j.mobile, b.time_to_payment, c.current_total, d.delayed_total, e.t2_total, e.t2_avg, f.t5_total, f.t5_avg, g.t6_total, g.t6_avg, h.t7_total, h.t7_avg, i.t8_total, i.t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, AVG(datediff(CURDATE(), a.end_date) - 2) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, AVG(datediff(CURDATE(), a.end_date) - 5) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, AVG(datediff(CURDATE(), a.end_date) - 6) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, AVG(datediff(CURDATE(), a.end_date) - 7) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, AVG(datediff(CURDATE(), a.end_date) - 8) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;" + - "SELECT district_code, district_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM district_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY district_code, date;" + - "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + - "SELECT district_code, block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,2) mrc_mre,ROUND(mre_wlg_mean,2) mre_wlg,ROUND(wlg_wls_mean,2) wlg_wls,ROUND(wls_fto_mean,2) wls_fto,ROUND(fto_firstsign_mean,2) fto_sn1,ROUND(firstsign_secondsign_mean,2) sn1_sn2,ROUND(secondsign_processed_mean,2) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY panchayat_code, date;" + + return "SELECT a.current_total, b.delayed_total, c.time_to_payment FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT a.block_code FROM blocks a RIGHT JOIN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") b ON a.district_code = b.region_code)) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT a.block_code FROM blocks a RIGHT JOIN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") b ON a.district_code = b.region_code)) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment, 1 AS merge FROM district_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + + "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, b.time_to_payment, c.current_total, d.delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;" + + "SELECT district_code, district_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM district_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY district_code, date;" + + "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + + "SELECT district_code, block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT a.block_code FROM blocks a RIGHT JOIN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") b ON a.district_code = b.region_code) ORDER BY panchayat_code, date;" + "SELECT state_code FROM districts WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + "SELECT * FROM contact;"; } From d44d549b7042af9146de9ae215088e827c8834df Mon Sep 17 00:00:00 2001 From: edodge Date: Fri, 29 Jul 2016 15:11:00 +0530 Subject: [PATCH 016/314] Add district performance stats to district cards API --- app/controllers/api/cards.js | 2 +- app/helpers/paydroid_parser.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/cards.js b/app/controllers/api/cards.js index 65c5fcf4..9d85f0a9 100644 --- a/app/controllers/api/cards.js +++ b/app/controllers/api/cards.js @@ -16,7 +16,7 @@ exports.getData = { var userId = request.auth.credentials.id; var role = request.auth.credentials.role; var version = request.pre.apiVersion; - + version = 2; var queryString = queries.cards(userId,role,version); // API CODE diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index bfbc8a07..e306a136 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -542,6 +542,7 @@ exports.v2 = function(rows, role) { 'cards_total': cards.length }, 'cards': cards, + 'district_performance': districtPerformance, 'block_performance': blockPerformance, 'panchayat_performance': panchayatPerformance, 'config': { From 9cc6bb4cb7b2bc1c8a1741b82b97d74f11735674 Mon Sep 17 00:00:00 2001 From: edodge Date: Fri, 29 Jul 2016 15:12:07 +0530 Subject: [PATCH 017/314] Remove version hardcode --- app/controllers/api/cards.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/cards.js b/app/controllers/api/cards.js index 9d85f0a9..65c5fcf4 100644 --- a/app/controllers/api/cards.js +++ b/app/controllers/api/cards.js @@ -16,7 +16,7 @@ exports.getData = { var userId = request.auth.credentials.id; var role = request.auth.credentials.role; var version = request.pre.apiVersion; - version = 2; + var queryString = queries.cards(userId,role,version); // API CODE From e1c364bba1069bd128513e4a0b327843594ab098 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Tue, 2 Aug 2016 12:51:47 +0530 Subject: [PATCH 018/314] Add cards react component --- app/templates/musters/current.hbs | 16 ++-------- assets/scripts/components/cards.jsx | 48 +++++++++++++++++++++++++++++ assets/scripts/index.js | 7 +---- tasks/webpack.js | 9 ++++-- 4 files changed, 59 insertions(+), 21 deletions(-) create mode 100644 assets/scripts/components/cards.jsx diff --git a/app/templates/musters/current.hbs b/app/templates/musters/current.hbs index d3f64ab7..9797c04c 100644 --- a/app/templates/musters/current.hbs +++ b/app/templates/musters/current.hbs @@ -1,4 +1,5 @@ -
+
+{{!--
{{>loader}}

{{t "/musters/current/title" credentials}}

@@ -8,17 +9,6 @@
  • {{t "/performance/discrete/grs_message" credentials}}
  • - - - - - - - - - - -
    Msr noWorkPanchayatGRSMobile
    {{> footer}} -
    + --}} diff --git a/assets/scripts/components/cards.jsx b/assets/scripts/components/cards.jsx new file mode 100644 index 00000000..f08d7992 --- /dev/null +++ b/assets/scripts/components/cards.jsx @@ -0,0 +1,48 @@ +import React from 'react'; +import {render} from 'react-dom'; + +var List = React.createClass({ + render: function(){ + return ( +
      + { + this.props.items.map(function(item) { + return
    • {item}
    • ; + }) + } +
    + ); + } +}); + +var FilteredList = React.createClass({ + filterList: function(event){ + var updatedList = this.state.initialItems; + updatedList = updatedList.filter(function(item){ + return item.toLowerCase().search(event.target.value.toLowerCase()) !== -1; + }); + this.setState({items: updatedList}); + }, + getInitialState: function(){ + return { + initialItems: [ + 'one', + 'two' + ], + items: [] + }; + }, + componentWillMount: function(){ + this.setState({items: this.state.initialItems}); + }, + render: function(){ + return ( +
    + + +
    + ); + } +}); + +render(, document.getElementById('cards')); diff --git a/assets/scripts/index.js b/assets/scripts/index.js index 0680d5c4..16640242 100644 --- a/assets/scripts/index.js +++ b/assets/scripts/index.js @@ -6,8 +6,6 @@ require('./components/active-link'); var OverviewPerformance = require('./performance/overview'); var DiscretePerformance = require('./performance/discrete'); -var currentMusters = require('./musters/current'); -var delayedMusters = require('./musters/delayed'); if (window.location.pathname === '/performance/overview') { OverviewPerformance.init(); @@ -17,11 +15,8 @@ if (window.location.pathname === '/performance/discrete') { } if (window.location.pathname === '/musters/current') { - currentMusters.init(); -} -if (window.location.pathname === '/musters/delayed') { - delayedMusters.init(); + require('./components/cards.jsx'); } if (window.location.pathname === '/login') { diff --git a/tasks/webpack.js b/tasks/webpack.js index d039ee4a..b71f84e9 100644 --- a/tasks/webpack.js +++ b/tasks/webpack.js @@ -9,6 +9,9 @@ var ProvidePlugin = Webpack.ProvidePlugin; Gulp.task('webpack', function() { + + var production = process.env.NODE_ENV === 'production'; + var config = { entry: { vendor: ['jquery', 'd3'], @@ -23,10 +26,12 @@ Gulp.task('webpack', function() { }, module: { loaders: [{ - test: /\.jsx$/, - loader: 'babel' + test: /\.jsx?$/, + loader: 'babel', + exclude: /(node_modules|bower_components)/ }] }, + debug: !production, devtool: 'source-map', plugins: [ new UglifyJsPlugin({ From 1da22760966d212f6007788be8fe037f347b897d Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Tue, 2 Aug 2016 13:07:49 +0530 Subject: [PATCH 019/314] Add cards api for musters --- .../{tiles/tiles.js => musters/cards.js} | 4 +- app/controllers/musters/current-musters.js | 47 ----------------- app/routes/musters.js | 52 +++++++------------ config/manifest.js | 5 -- 4 files changed, 23 insertions(+), 85 deletions(-) rename app/controllers/{tiles/tiles.js => musters/cards.js} (97%) delete mode 100644 app/controllers/musters/current-musters.js diff --git a/app/controllers/tiles/tiles.js b/app/controllers/musters/cards.js similarity index 97% rename from app/controllers/tiles/tiles.js rename to app/controllers/musters/cards.js index 1d072b58..b18a926e 100644 --- a/app/controllers/tiles/tiles.js +++ b/app/controllers/musters/cards.js @@ -3,6 +3,8 @@ var Queries = require('../../helpers/queries'); var OverviewParser = require('../../helpers/overview_parser'); var Translate = require('../../templates/helpers/t'); +var utils = require('../../helpers/utils'); +var d3 = require(d3); exports.showPage = { handler: function(request, reply) { @@ -81,7 +83,7 @@ exports.getData = { } if (role === 'district') { - + // } var final_dict = { diff --git a/app/controllers/musters/current-musters.js b/app/controllers/musters/current-musters.js deleted file mode 100644 index 57b13e83..00000000 --- a/app/controllers/musters/current-musters.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict'; - -var Queries = require('../../helpers/queries'); -var utils = require('../../helpers/utils'); -var req = require('request'); - -exports.showPage = { - handler: function(request, reply) { - return reply.view('musters/current'); - } -}; - -exports.getData = { - handler: function(request, reply) { - - var sequelize = request.server.plugins.sequelize.db.sequelize; - var active_region = request.query.active_region; - var queryString = Queries.current_musters(active_region); - - sequelize.query(queryString, { - type: sequelize.QueryTypes.SELECT - }).then(function(rows) { - - var mustersResponse = utils.flatten(rows[0]); - var mappingResponse = utils.flatten(rows[1]); - - var final_dict = { - 'musters': mustersResponse.map(function(d) { - return { - 'msr_no':d.msr_no, - 'work':d.work_name, - 'panchayat':d.panchayat_name, - 'grs':d.name, - 'mobile':d.mobile_no - }; - }), - 'mapping': { - 'total_panchayat_count': mappingResponse[0].total_panchayat_count, - 'grs_panchayat_count': mappingResponse[0].grs_panchayat_count, - } - - }; - - reply(final_dict); - }); - } -}; diff --git a/app/routes/musters.js b/app/routes/musters.js index 40217d07..6b9130d3 100644 --- a/app/routes/musters.js +++ b/app/routes/musters.js @@ -2,40 +2,28 @@ exports.register = function(plugin, options, next) { - var Controllers = { - musters: { - current: require('../controllers/musters/current-musters'), - delayed: require('../controllers/musters/delayed-musters') - } - }; + var Controllers = { + musters: { + cards: require('../controllers/musters/cards') + } + }; - plugin.route([ + plugin.route([ - // Block Dashoard - { - method: 'GET', - path: '/musters/current', - config: Controllers.musters.current.showPage - }, - // Block Dashoard - { - method: 'GET', - path: '/musters/current/data', - config: Controllers.musters.current.getData - }, - // Panchayat Dashboard - { - method: 'GET', - path: '/musters/delayed', - config: Controllers.musters.delayed.showPage - }, - // Block Dashoard - { - method: 'GET', - path: '/musters/delayed/data', - config: Controllers.musters.delayed.getData - }, - ]); + // Muster cards + { + method: 'GET', + path: '/musters/cards', + config: Controllers.musters.cards.showPage + }, + + // Muster cards data + { + method: 'GET', + path: '/musters/cards/data', + config: Controllers.musters.cards.getData + }, + ]); next(); }; diff --git a/config/manifest.js b/config/manifest.js index 37232fec..073becd8 100644 --- a/config/manifest.js +++ b/config/manifest.js @@ -154,11 +154,6 @@ internals.manifest = { plugin: './app/routes/musters.js' }, - // Alerts routes - { - plugin: './app/routes/alerts.js' - }, - // Api routes { plugin: './app/routes/api.js' From 161edb21b832effaeb9ed069a8335346b902ce75 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Tue, 2 Aug 2016 13:11:25 +0530 Subject: [PATCH 020/314] Cleanup unused routes --- app/controllers/musters/cards.js | 2 +- app/controllers/musters/delayed-musters.js | 90 ---------------------- app/routes/alerts.js | 34 -------- app/routes/monitor.js | 65 ---------------- 4 files changed, 1 insertion(+), 190 deletions(-) delete mode 100644 app/controllers/musters/delayed-musters.js delete mode 100644 app/routes/alerts.js delete mode 100644 app/routes/monitor.js diff --git a/app/controllers/musters/cards.js b/app/controllers/musters/cards.js index b18a926e..c44a1be2 100644 --- a/app/controllers/musters/cards.js +++ b/app/controllers/musters/cards.js @@ -8,7 +8,7 @@ var d3 = require(d3); exports.showPage = { handler: function(request, reply) { - // return reply.view('performance/overview'); + return reply.view('musters/cards'); } }; diff --git a/app/controllers/musters/delayed-musters.js b/app/controllers/musters/delayed-musters.js deleted file mode 100644 index 0ed479d7..00000000 --- a/app/controllers/musters/delayed-musters.js +++ /dev/null @@ -1,90 +0,0 @@ -'use strict'; - -var Queries = require('../../helpers/queries'); -var utils = require('../../helpers/utils'); -var req = require('request'); - -exports.showPage = { - handler: function(request, reply) { - return reply.view('musters/delayed'); - } -}; - -exports.getData = { - handler: function(request, reply) { - - var sequelize = request.server.plugins.sequelize.db.sequelize; - var active_region = request.query.active_region; - var queryString = Queries.delayed_musters(active_region); - - sequelize.query(queryString, { - type: sequelize.QueryTypes.SELECT - }).then(function(rows) { - var mustersResponse = utils.flatten(rows[0]); - var mappingResponse = utils.flatten(rows[1]); - - var final_dict = { - 'musters': { - 'ds_t2': mustersResponse.filter(function(d) { return d.step==='ds_t2'; }).map(function(d) { - return { - 'msr_no':d.msr_no, - 'work':d.work_name, - 'panchayat':d.panchayat_name, - 'closure_date':d.end_date, - 'days_pending':d.days_pending, - 'grs_name':d.name, - 'mobile':d.mobile_no - }; - }), - 'ds_t5': mustersResponse.filter(function(d) { return d.step==='ds_t5'; }).map(function(d) { - return { - 'msr_no':d.msr_no, - 'work':d.work_name, - 'panchayat':d.panchayat_name, - 'closure_date':d.end_date, - 'days_pending':d.days_pending, - 'ta_name':d.name, - 'mobile':d.mobile_no - }; - }), - 'ds_t6': mustersResponse.filter(function(d) { return d.step==='ds_t6'; }).map(function(d) { - return { - 'msr_no':d.msr_no, - 'work':d.work_name, - 'panchayat':d.panchayat_name, - 'closure_date':d.end_date, - 'days_pending':d.days_pending - }; - }), - 'ds_t7': mustersResponse.filter(function(d) { return d.step==='ds_t7'; }).map(function(d) { - return { - 'msr_no':d.msr_no, - 'work':d.work_name, - 'panchayat':d.panchayat_name, - 'closure_date':d.end_date, - 'days_pending':d.days_pending - }; - }), - 'ds_t8': mustersResponse.filter(function(d) { return d.step==='ds_t8'; }).map(function(d) { - return { - 'msr_no':d.msr_no, - 'work':d.work_name, - 'panchayat':d.panchayat_name, - 'closure_date':d.end_date, - 'days_pending':d.days_pending - }; - }) - - }, - 'mapping': { - 'total_panchayat_count': mappingResponse[0].total_panchayat_count, - 'grs_panchayat_count': mappingResponse[0].grs_panchayat_count, - 'ta_panchayat_count': mappingResponse[0].ta_panchayat_count - } - - }; - - reply(final_dict); - }); - } -}; diff --git a/app/routes/alerts.js b/app/routes/alerts.js deleted file mode 100644 index 37a0ac18..00000000 --- a/app/routes/alerts.js +++ /dev/null @@ -1,34 +0,0 @@ -'use strict'; - -exports.register = function(plugin, options, next) { - - var Controllers = { - alerts: { - notifications: require('../controllers/alerts/notifications') - // feedbacks: require('../controllers/alerts/feedbacks') - } - }; - - plugin.route([ - - // Show Notifications - { - method: 'GET', - path: '/notifications/read', - config: Controllers.alerts.notifications.showReadNotifications - }, - // Show Notifications - { - method: 'GET', - path: '/notifications/unread', - config: Controllers.alerts.notifications.showUnreadNotifications - } - ]); - - next(); -}; - -exports.register.attributes = { - name: 'alert_routes', - version: require('../../package.json').version -}; diff --git a/app/routes/monitor.js b/app/routes/monitor.js deleted file mode 100644 index f85c584d..00000000 --- a/app/routes/monitor.js +++ /dev/null @@ -1,65 +0,0 @@ -'use strict'; - -exports.register = function(plugin, options, next) { - - var Controllers = { - monitor: { - user: require('../controllers/monitor/user'), - server: require('../controllers/monitor/server'), - analysis: require('../controllers/monitor/analysis') - } - }; - - plugin.route([ - - // User monitororing dashbaord - { - method: 'GET', - path: '/monitor/user', - config: Controllers.monitor.user.showPage - }, - // User monitoring data - { - method: 'GET', - path: '/monitor/user/data', - config: Controllers.monitor.user.getData - }, - // Server monitoring - { - method: 'GET', - path: '/monitor/server', - config: Controllers.monitor.server.showPage - }, - // Server monitoring - { - method: 'GET', - path: '/monitor/server/data', - config: Controllers.monitor.server.getData - }, - // Server monitoring - { - method: 'GET', - path: '/monitor/server/pageloaddata', - config: Controllers.monitor.server.getPageLoadData - }, - // Analysis monitoring - { - method: 'GET', - path: '/monitor/analysis', - config: Controllers.monitor.analysis.showPage - }, - // Analysis monitoring data api - { - method: 'GET', - path: '/monitor/analysis/data', - config: Controllers.monitor.analysis.getData - } - ]); - - next(); -}; - -exports.register.attributes = { - name: 'monitor_routes', - version: require('../../package.json').version -}; From 246c25f0c8fd52ed10f4c62437d14d3509070b16 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Tue, 2 Aug 2016 13:16:25 +0530 Subject: [PATCH 021/314] Cleanup assets config --- config/assets.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/config/assets.js b/config/assets.js index 484921bc..dd13e20c 100644 --- a/config/assets.js +++ b/config/assets.js @@ -1,13 +1,17 @@ 'use strict'; -var Confidence = require('confidence'); + +const Confidence = require('confidence'); // Confidence criteria -var criteria = { - env: process.env.NODE_ENV +let internals = { + criteria: { + env: process.env.NODE_ENV + } }; -// Confidence document object for gulp tasks -var paths = { +// Confidence document object for gulp tasks + +internals.paths = { fonts: ['./assets/fonts/*'], styles: ['./assets/styles/**/*'], images: ['./assets/images/**/*'], @@ -26,11 +30,12 @@ var paths = { ] }; -var store = new Confidence.Store(paths); +internals.store = new Confidence.Store(internals.config); exports.get = function(key) { - return store.get(key, criteria); + return internals.store.get(key, internals.criteria); }; + exports.meta = function(key) { - return store.meta(key, criteria); + return internals.store.meta(key, internals.criteria); }; From 9c1a6232716799ffbb24cf64a33b8d944d53995a Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Tue, 2 Aug 2016 13:18:37 +0530 Subject: [PATCH 022/314] Update config.example --- config/config.example.js | 64 ++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/config/config.example.js b/config/config.example.js index 19876776..d4f50fdd 100644 --- a/config/config.example.js +++ b/config/config.example.js @@ -1,15 +1,19 @@ 'use strict'; -var Confidence = require('confidence'); + +const Confidence = require('confidence'); // Confidence criteria -var criteria = { - env: process.env.NODE_ENV +let internals = { + criteria: { + env: process.env.NODE_ENV + } }; // Confidence document object -var config = { - $meta: 'paydash app configuration file', - projectName: 'paydash', + +internals.config = { + $meta: 'Paydash app configuration file', + projectName: 'Paydash', port: { web: { $filter: 'env', @@ -21,7 +25,7 @@ var config = { baseUrl: { $filter: 'env', $meta: 'values should not end in "/"', - production: 'https://example.yourdomain.com', + production: 'https://paydash.in', $default: 'http://127.0.0.1:8000' }, sequelize: { @@ -30,7 +34,7 @@ var config = { database: 'db_name', username: 'username', password: 'password', - host: 'db_host_address', + host: 'host.name', dialect: 'mysql', pool: { max: 5, @@ -39,10 +43,10 @@ var config = { } }, test: { - database: 'paydash', + database: 'db_name', username: 'username', password: 'password', - host: 'localhost', + host: 'host.name', dialect: 'mysql', pool: { max: 5, @@ -51,10 +55,10 @@ var config = { } }, $default: { - database: 'paydash', - username: 'root', - password: '', - host: 'localhost', + database: 'db_name', + username: 'username', + password: 'password', + host: 'host.name', dialect: 'mysql', pool: { max: 5, @@ -64,37 +68,21 @@ var config = { } }, yarCookie: { - password: 'your_cookie_secret', + password: 'cookiepasswordhere', ssl: false }, authCookie: { - cookieSecret: 'your_auth_cookie_secret', + cookieSecret: 'cookiesecrethere', cookieName: 'Basic-auth' - }, - good: { - opsInterval: 1000, - reporters: [{ - reporter: 'good-file', - events: { - ops: '*' - }, - config: { - path: 'logs/ops/', - rotate: 'daily', - prefix: 'payops' - } - }, { - reporter: 'good-file', - events: { - error: '*' - }, - config: 'logs/error.json' - }] } }; -var store = new Confidence.Store(config); +internals.store = new Confidence.Store(internals.config); exports.get = function(key) { - return store.get(key, criteria); + return internals.store.get(key, internals.criteria); +}; + +exports.meta = function(key) { + return internals.store.meta(key, internals.criteria); }; From 9dde2357243ac83b7c4d79ef80bd7bf0a190c5f9 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Tue, 2 Aug 2016 13:21:01 +0530 Subject: [PATCH 023/314] Cleanup routes --- app/routes/api.js | 2 +- app/routes/auth.js | 2 +- app/routes/core.js | 2 +- app/routes/musters.js | 2 +- app/routes/performance.js | 67 +++++++++++++++++++-------------------- app/routes/users.js | 64 ++++++++++++++++++------------------- 6 files changed, 69 insertions(+), 70 deletions(-) diff --git a/app/routes/api.js b/app/routes/api.js index e49aef28..b381d5da 100644 --- a/app/routes/api.js +++ b/app/routes/api.js @@ -2,7 +2,7 @@ exports.register = function(plugin, options, next) { - var Controllers = { + const Controllers = { api: { login: require('../controllers/api/login'), logout: require('../controllers/api/logout'), diff --git a/app/routes/auth.js b/app/routes/auth.js index 80395341..0f5a3388 100644 --- a/app/routes/auth.js +++ b/app/routes/auth.js @@ -2,7 +2,7 @@ exports.register = function(plugin, options, next) { - var Controllers = { + const Controllers = { auth: { login: require('../controllers/auth/login'), logout: require('../controllers/auth/logout') diff --git a/app/routes/core.js b/app/routes/core.js index ba63870b..c30a17d5 100644 --- a/app/routes/core.js +++ b/app/routes/core.js @@ -2,7 +2,7 @@ exports.register = function(plugin, options, next) { - var Controllers = { + const Controllers = { core: { pages: require('../controllers/core/pages'), fallback: require('../controllers/core/fallback'), diff --git a/app/routes/musters.js b/app/routes/musters.js index 6b9130d3..d467bcc7 100644 --- a/app/routes/musters.js +++ b/app/routes/musters.js @@ -2,7 +2,7 @@ exports.register = function(plugin, options, next) { - var Controllers = { + const Controllers = { musters: { cards: require('../controllers/musters/cards') } diff --git a/app/routes/performance.js b/app/routes/performance.js index 0b742ee4..13fe4f45 100644 --- a/app/routes/performance.js +++ b/app/routes/performance.js @@ -2,42 +2,41 @@ exports.register = function(plugin, options, next) { - var Controllers = { - performance: { - overview: require('../controllers/performance/overview'), - discrete: require('../controllers/performance/discrete'), - panchayat: require('../controllers/performance/panchayat') - } - }; + const Controllers = { + performance: { + overview: require('../controllers/performance/overview'), + discrete: require('../controllers/performance/discrete'), + panchayat: require('../controllers/performance/panchayat') + } + }; - plugin.route([ + plugin.route([ - // Overview Performance - { - method: 'GET', - path: '/performance/overview', - config: Controllers.performance.overview.showPage - }, { - method: 'GET', - path: '/performance/overview/data', - config: Controllers.performance.overview.getData - }, - // Discrete Performance - { - method: 'GET', - path: '/performance/discrete', - config: Controllers.performance.discrete.showPage - }, { - method: 'GET', - path: '/performance/discrete/data', - config: Controllers.performance.discrete.getData - }, - { - method: 'GET', - path: '/performance/panchayat/data', - config: Controllers.performance.panchayat.getData - } - ]); + // Overview Performance + { + method: 'GET', + path: '/performance/overview', + config: Controllers.performance.overview.showPage + }, { + method: 'GET', + path: '/performance/overview/data', + config: Controllers.performance.overview.getData + }, + // Discrete Performance + { + method: 'GET', + path: '/performance/discrete', + config: Controllers.performance.discrete.showPage + }, { + method: 'GET', + path: '/performance/discrete/data', + config: Controllers.performance.discrete.getData + }, { + method: 'GET', + path: '/performance/panchayat/data', + config: Controllers.performance.panchayat.getData + } + ]); next(); }; diff --git a/app/routes/users.js b/app/routes/users.js index b4c038b2..c0757bce 100644 --- a/app/routes/users.js +++ b/app/routes/users.js @@ -2,40 +2,40 @@ exports.register = function(plugin, options, next) { - var Controllers = { - settings: { - profile: require('../controllers/users/settings-profile'), - account: require('../controllers/users/settings-account') - } - }; + const Controllers = { + settings: { + profile: require('../controllers/users/settings-profile'), + account: require('../controllers/users/settings-account') + } + }; - plugin.route([ + plugin.route([ - // Settings - Show Edit profile - { - method: 'GET', - path: '/me/settings/profile', - config: Controllers.settings.profile.showEditProfile - }, - // Settings - Post Edit profile - { - method: 'POST', - path: '/me/settings/profile', - config: Controllers.settings.profile.postEditProfile - }, - // Settings - Show Edit account - { - method: 'GET', - path: '/me/settings/account', - config: Controllers.settings.account.showEditAccount - }, - // Settings - Post Edit account for change password - { - method: 'POST', - path: '/me/settings/account/change-password', - config: Controllers.settings.account.postChangePassword - } - ]); + // Settings - Show Edit profile + { + method: 'GET', + path: '/me/settings/profile', + config: Controllers.settings.profile.showEditProfile + }, + // Settings - Post Edit profile + { + method: 'POST', + path: '/me/settings/profile', + config: Controllers.settings.profile.postEditProfile + }, + // Settings - Show Edit account + { + method: 'GET', + path: '/me/settings/account', + config: Controllers.settings.account.showEditAccount + }, + // Settings - Post Edit account for change password + { + method: 'POST', + path: '/me/settings/account/change-password', + config: Controllers.settings.account.postChangePassword + } + ]); next(); }; From 717328e00e565bec8ca3d7e56c1761428431cd7a Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Tue, 2 Aug 2016 13:37:13 +0530 Subject: [PATCH 024/314] Cleanup controllers --- app/controllers/alerts/notifications.js | 75 -- app/controllers/api/cards.js | 1154 ++++++++++----------- app/controllers/monitor/analysis.js | 78 -- app/controllers/monitor/server.js | 57 - app/controllers/monitor/user.js | 49 - app/controllers/musters/cards.js | 74 +- app/controllers/users/settings-account.js | 8 +- app/controllers/users/settings-profile.js | 2 +- app/helpers/notifier.js | 42 - app/helpers/paydroid_parser.js | 6 +- app/helpers/utils.js | 19 +- 11 files changed, 630 insertions(+), 934 deletions(-) delete mode 100644 app/controllers/alerts/notifications.js delete mode 100644 app/controllers/monitor/analysis.js delete mode 100644 app/controllers/monitor/server.js delete mode 100644 app/controllers/monitor/user.js delete mode 100644 app/helpers/notifier.js diff --git a/app/controllers/alerts/notifications.js b/app/controllers/alerts/notifications.js deleted file mode 100644 index cbdb663c..00000000 --- a/app/controllers/alerts/notifications.js +++ /dev/null @@ -1,75 +0,0 @@ -'use strict'; - -var Joi = require('joi'); -var _ = require('lodash'); -var Notifier = require('../../helpers/notifier'); - -exports.showUnreadNotifications = { - description: 'Show unread notifications', - handler: function(request, reply) { - - var db = request.server.plugins.sequelize.db; - var notifications = request.server.plugins.sequelize.db.notifications; - var ctx = { - notifications: null - }; - notifications.findAll({ - where: { - user_id: request.auth.credentials.id, - viewed: 0 - } - - }).then(function(unread) { - - unread.forEach(function(n) { - n.dataValues.msg = Notifier.message(n, request); - }); - - ctx.notifications = _.groupBy(unread, function(n) { - return n.batch_id; - }); - - notifications.update({ - viewed: 1 - }, { - where: { - user_id: request.auth.credentials.id, - viewed: 0 - } - }); - reply.view('alerts/notifications-unread', ctx); - }); - - } -}; - -exports.showReadNotifications = { - description: 'Show notifications', - handler: function(request, reply) { - - var db = request.server.plugins.sequelize.db; - var notifications = request.server.plugins.sequelize.db.notifications; - var ctx = { - notifications: null - }; - - notifications.findAll({ - where: { - user_id: request.auth.credentials.id, - viewed: 1 - } - }).then(function(read) { - - read.forEach(function(n) { - n.dataValues.msg = Notifier.message(n, request); - }); - - ctx.notifications = _.groupBy(read, function(n) { - return n.batch_id; - }); - - reply.view('alerts/notifications-read', ctx); - }); - - } -}; diff --git a/app/controllers/api/cards.js b/app/controllers/api/cards.js index 4d4bf850..42c19838 100644 --- a/app/controllers/api/cards.js +++ b/app/controllers/api/cards.js @@ -19,589 +19,589 @@ exports.getData = { var role = request.auth.credentials.role; var version = request.pre.apiVersion; - var queryString = queries.cards(userId,role,version); + var queryString = queries.cards(userId, role, version); // API CODE sequelize.query(queryString, { type: sequelize.QueryTypes.SELECT }).then(function(rows) { - if (version===1) { - - var overviewResponse = utils.flatten(rows[0]); - - var cardsResponse = utils.flatten(rows[1]); - - var blockResponse = utils.flatten(rows[2]); - - var panchayatResponse = utils.flatten(rows[3]); - - var notificationsResponse = utils.flatten(rows[4]); - - var stateResponse = utils.flatten(rows[5]); - - var contactResponse = utils.flatten(rows[6]); - - // Parse the overview response - var current_total = overviewResponse[0].current_total; - var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].time_to_payment; - var total_transactions = overviewResponse[0].total_transactions; - - var state_code = stateResponse[0].state_code; - - // Nest the cards response and include the overview stats - var cards = d3.nest() - .key(function(d) { - var key = d.staff_id; - return key; - }) - .rollup(function(v) { - return { - 'name': v[0].name, - 'staff_id': v[0].staff_id, - 'designation': utils.getDesignation(v[0].task_assign, state_code), - 'mobile': v[0].mobile_no, - 'block_name': v[0].block_name, - 'current_total': v[0].current_total, - 'delayed_total': v[0].delayed_total, - 'delayed_musters': v.filter(function(d) { - return d.type === 'delayed_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date, - 'days_pending': d.days_pending - }]; - }), - 'current_musters': v.filter(function(d) { - return d.type === 'current_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date - }]; - }) - }; - }) - .entries(cardsResponse) - .map(function(d) { - return d.values; - }); - - - // Nest the block response - var blockPerformance = d3.nest() - .key(function(d) { - return d.block_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'block_name': v[0].block_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(blockResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - - // Nest the panchayat response - var panchayatPerformance = d3.nest() - .key(function(d) { - return d.panchayat_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'panchayat_code': v[0].panchayat_code, - 'panchayat_name': v[0].panchayat_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(panchayatResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; - - var data = { - 'overview': { - 'current_total': current_total, - 'delayed_total': delayed_total, - 'days_to_payment': days_to_payment, - 'total_transactions': total_transactions, - 'cards_total': cards.length - }, - 'cards': cards, - 'block_performance': blockPerformance, - 'panchayat_performance': panchayatPerformance, - 'notifications': notificationsResponse, - 'config': { - 'headers': headers, - labels: [ - 'Date', - 'Muster roll closure to muster roll entry', - 'Muster roll entry to wage list generation', - 'Wage list generation to wage list sent', - 'Wage list sent to FTO generation', - 'FTO generation to first signature', - 'First signature to second signature', - 'Second signature to processed by bank', - 'Total Transactions' - ], - }, - 'contact': { - 'phone': contactResponse[0].phone, - 'email': contactResponse[0].email, - 'subject': contactResponse[0].subject - } - }; - - reply(data); - } else if (version===2) { - - if (role==='block') { - - var overviewResponse = utils.flatten(rows[0]); - - var cardsResponse = utils.flatten(rows[1]); - - var blockResponse = utils.flatten(rows[2]); - - var panchayatResponse = utils.flatten(rows[3]); - - var stateResponse = utils.flatten(rows[4]); - - var contactResponse = utils.flatten(rows[5]); - - // Parse the overview response - var current_total = overviewResponse[0].current_total; - var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].time_to_payment; - - var state_code = stateResponse[0].state_code; - - // Nest the cards response and include the overview stats - var cards = d3.nest() - .key(function(d) { - var key = d.staff_id + d.block_code; - return key; - }) - .rollup(function(v) { - return { - 'name': v[0].name, - 'staff_id': v[0].staff_id, - 'designation': utils.getDesignation(v[0].task_assign, state_code), - 'mobile': v[0].mobile_no, - 'block_name': v[0].block_name, - 'current_total': v[0].current_total, - 'delayed_total': v[0].delayed_total, - 'delayed_musters': v.filter(function(d) { - return d.type === 'delayed_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date, - 'days_pending': d.days_pending - }]; - }), - 'current_musters': v.filter(function(d) { - return d.type === 'current_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date - }]; - }) - }; - }) - .entries(cardsResponse) - .map(function(d) { - return d.values; - }); - - - // Nest the block response - var blockPerformance = d3.nest() - .key(function(d) { - return d.block_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'block_name': v[0].block_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(blockResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - - // Nest the panchayat response - var panchayatPerformance = d3.nest() - .key(function(d) { - return d.panchayat_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'panchayat_code': v[0].panchayat_code, - 'panchayat_name': v[0].panchayat_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(panchayatResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; - - var data = { - 'overview': { - 'current_total': current_total, - 'delayed_total': delayed_total, - 'days_to_payment': days_to_payment, - 'cards_total': cards.length - }, - 'cards': cards, - 'block_performance': blockPerformance, - 'panchayat_performance': panchayatPerformance, - 'config': { - 'headers': headers, - labels: [ - 'Date', - 'Muster roll closure to muster roll entry', - 'Muster roll entry to wage list generation', - 'Wage list generation to wage list sent', - 'Wage list sent to FTO generation', - 'FTO generation to first signature', - 'First signature to second signature', - 'Second signature to processed by bank', - 'Total Transactions' - ], - }, - 'contact': { - 'phone': contactResponse[0].phone, - 'email': contactResponse[0].email, - 'subject': contactResponse[0].subject - } - }; - - reply(data); - - } else if (role==='district') { - - var overviewResponse = utils.flatten(rows[0]); - - var cardsResponse = utils.flatten(rows[1]); - - var districtResponse = utils.flatten(rows[2]); - - var blockResponse = utils.flatten(rows[3]); - - var panchayatResponse = utils.flatten(rows[4]); - - var stateResponse = utils.flatten(rows[5]); - - var contactResponse = utils.flatten(rows[6]); - - // Parse the overview response - var current_total = overviewResponse[0].current_total; - var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].time_to_payment; - - var state_code = stateResponse[0].state_code; - - // Nest the cards response and include the overview stats - var cards = d3.nest() - .key(function(d) { - var key = d.staff_id + d.district_code; - return key; - }) - .rollup(function(v) { - return { - 'name': v[0].name, - 'staff_id': v[0].staff_id, - 'designation': utils.getDesignation(v[0].task_assign, state_code), - 'mobile': v[0].mobile_no, - 'district_name': v[0].block_name, - 'current_total': v[0].current_total, - 'delayed_total': v[0].delayed_total, - 'delayed_musters': v.filter(function(d) { - return d.type === 'delayed_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date, - 'days_pending': d.days_pending - }]; - }), - 'current_musters': v.filter(function(d) { - return d.type === 'current_musters'; - }).map(function(d) { - return [{ - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date - }]; - }) - }; - }) - .entries(cardsResponse) - .map(function(d) { - return d.values; - }); - - // Nest the district response - var districtPerformance = d3.nest() - .key(function(d) { - return d.district_code; - }) - .rollup(function(v) { - return { - 'district_code': v[0].block_code, - 'district_name': v[0].block_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(districtResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - - // Nest the block response - var blockPerformance = d3.nest() - .key(function(d) { - return d.block_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].block_code, - 'block_name': v[0].block_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(blockResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - - // Nest the panchayat response - var panchayatPerformance = d3.nest() - .key(function(d) { - return d.panchayat_code; - }) - .rollup(function(v) { - return { - 'district_code': v[0].district_code, - 'block_code': v[0].block_code, - 'panchayat_code': v[0].panchayat_code, - 'panchayat_name': v[0].panchayat_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(panchayatResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; - - var data = { - 'overview': { - 'current_total': current_total, - 'delayed_total': delayed_total, - 'days_to_payment': days_to_payment, - 'cards_total': cards.length - }, - 'cards': cards, - 'block_performance': blockPerformance, - 'panchayat_performance': panchayatPerformance, - 'config': { - 'headers': headers, - labels: [ - 'Date', - 'Muster roll closure to muster roll entry', - 'Muster roll entry to wage list generation', - 'Wage list generation to wage list sent', - 'Wage list sent to FTO generation', - 'FTO generation to first signature', - 'First signature to second signature', - 'Second signature to processed by bank', - 'Total Transactions' - ], - }, - 'contact': { - 'phone': contactResponse[0].phone, - 'email': contactResponse[0].email, - 'subject': contactResponse[0].subject - } - }; - - reply(data); - - } - } - + if (version === 1) { + + var overviewResponse = utils.flatten(rows[0]); + + var cardsResponse = utils.flatten(rows[1]); + + var blockResponse = utils.flatten(rows[2]); + + var panchayatResponse = utils.flatten(rows[3]); + + var notificationsResponse = utils.flatten(rows[4]); + + var stateResponse = utils.flatten(rows[5]); + + var contactResponse = utils.flatten(rows[6]); + + // Parse the overview response + var current_total = overviewResponse[0].current_total; + var delayed_total = overviewResponse[0].delayed_total; + var days_to_payment = overviewResponse[0].time_to_payment; + var total_transactions = overviewResponse[0].total_transactions; + + var state_code = stateResponse[0].state_code; + + // Nest the cards response and include the overview stats + var cards = d3.nest() + .key(function(d) { + var key = d.staff_id; + return key; + }) + .rollup(function(v) { + return { + 'name': v[0].name, + 'staff_id': v[0].staff_id, + 'designation': utils.getDesignation(v[0].task_assign, state_code), + 'mobile': v[0].mobile_no, + 'block_name': v[0].block_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'delayed_musters': v.filter(function(d) { + return d.type === 'delayed_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date, + 'days_pending': d.days_pending + }]; + }), + 'current_musters': v.filter(function(d) { + return d.type === 'current_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date + }]; + }) + }; + }) + .entries(cardsResponse) + .map(function(d) { + return d.values; + }); + + + // Nest the block response + var blockPerformance = d3.nest() + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(blockResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + + // Nest the panchayat response + var panchayatPerformance = d3.nest() + .key(function(d) { + return d.panchayat_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'panchayat_code': v[0].panchayat_code, + 'panchayat_name': v[0].panchayat_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(panchayatResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; + + var data = { + 'overview': { + 'current_total': current_total, + 'delayed_total': delayed_total, + 'days_to_payment': days_to_payment, + 'total_transactions': total_transactions, + 'cards_total': cards.length + }, + 'cards': cards, + 'block_performance': blockPerformance, + 'panchayat_performance': panchayatPerformance, + 'notifications': notificationsResponse, + 'config': { + 'headers': headers, + labels: [ + 'Date', + 'Muster roll closure to muster roll entry', + 'Muster roll entry to wage list generation', + 'Wage list generation to wage list sent', + 'Wage list sent to FTO generation', + 'FTO generation to first signature', + 'First signature to second signature', + 'Second signature to processed by bank', + 'Total Transactions' + ], + }, + 'contact': { + 'phone': contactResponse[0].phone, + 'email': contactResponse[0].email, + 'subject': contactResponse[0].subject + } + }; + + reply(data); + } else if (version === 2) { + + if (role === 'block') { + + var overviewResponse = utils.flatten(rows[0]); + + var cardsResponse = utils.flatten(rows[1]); + + var blockResponse = utils.flatten(rows[2]); + + var panchayatResponse = utils.flatten(rows[3]); + + var stateResponse = utils.flatten(rows[4]); + + var contactResponse = utils.flatten(rows[5]); + + // Parse the overview response + var current_total = overviewResponse[0].current_total; + var delayed_total = overviewResponse[0].delayed_total; + var days_to_payment = overviewResponse[0].time_to_payment; + + var state_code = stateResponse[0].state_code; + + // Nest the cards response and include the overview stats + var cards = d3.nest() + .key(function(d) { + var key = d.staff_id + d.block_code; + return key; + }) + .rollup(function(v) { + return { + 'name': v[0].name, + 'staff_id': v[0].staff_id, + 'designation': utils.getDesignation(v[0].task_assign, state_code), + 'mobile': v[0].mobile_no, + 'block_name': v[0].block_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'delayed_musters': v.filter(function(d) { + return d.type === 'delayed_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date, + 'days_pending': d.days_pending + }]; + }), + 'current_musters': v.filter(function(d) { + return d.type === 'current_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date + }]; + }) + }; + }) + .entries(cardsResponse) + .map(function(d) { + return d.values; + }); + + + // Nest the block response + var blockPerformance = d3.nest() + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(blockResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + + // Nest the panchayat response + var panchayatPerformance = d3.nest() + .key(function(d) { + return d.panchayat_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'panchayat_code': v[0].panchayat_code, + 'panchayat_name': v[0].panchayat_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(panchayatResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; + + var data = { + 'overview': { + 'current_total': current_total, + 'delayed_total': delayed_total, + 'days_to_payment': days_to_payment, + 'cards_total': cards.length + }, + 'cards': cards, + 'block_performance': blockPerformance, + 'panchayat_performance': panchayatPerformance, + 'config': { + 'headers': headers, + labels: [ + 'Date', + 'Muster roll closure to muster roll entry', + 'Muster roll entry to wage list generation', + 'Wage list generation to wage list sent', + 'Wage list sent to FTO generation', + 'FTO generation to first signature', + 'First signature to second signature', + 'Second signature to processed by bank', + 'Total Transactions' + ], + }, + 'contact': { + 'phone': contactResponse[0].phone, + 'email': contactResponse[0].email, + 'subject': contactResponse[0].subject + } + }; + + reply(data); + + } else if (role === 'district') { + + var overviewResponse = utils.flatten(rows[0]); + + var cardsResponse = utils.flatten(rows[1]); + + var districtResponse = utils.flatten(rows[2]); + + var blockResponse = utils.flatten(rows[3]); + + var panchayatResponse = utils.flatten(rows[4]); + + var stateResponse = utils.flatten(rows[5]); + + var contactResponse = utils.flatten(rows[6]); + + // Parse the overview response + var current_total = overviewResponse[0].current_total; + var delayed_total = overviewResponse[0].delayed_total; + var days_to_payment = overviewResponse[0].time_to_payment; + + var state_code = stateResponse[0].state_code; + + // Nest the cards response and include the overview stats + var cards = d3.nest() + .key(function(d) { + var key = d.staff_id + d.district_code; + return key; + }) + .rollup(function(v) { + return { + 'name': v[0].name, + 'staff_id': v[0].staff_id, + 'designation': utils.getDesignation(v[0].task_assign, state_code), + 'mobile': v[0].mobile_no, + 'district_name': v[0].block_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'delayed_musters': v.filter(function(d) { + return d.type === 'delayed_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date, + 'days_pending': d.days_pending + }]; + }), + 'current_musters': v.filter(function(d) { + return d.type === 'current_musters'; + }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date + }]; + }) + }; + }) + .entries(cardsResponse) + .map(function(d) { + return d.values; + }); + + // Nest the district response + var districtPerformance = d3.nest() + .key(function(d) { + return d.district_code; + }) + .rollup(function(v) { + return { + 'district_code': v[0].block_code, + 'district_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(districtResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + + // Nest the block response + var blockPerformance = d3.nest() + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(blockResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + + // Nest the panchayat response + var panchayatPerformance = d3.nest() + .key(function(d) { + return d.panchayat_code; + }) + .rollup(function(v) { + return { + 'district_code': v[0].district_code, + 'block_code': v[0].block_code, + 'panchayat_code': v[0].panchayat_code, + 'panchayat_name': v[0].panchayat_name, + 'data': v.map(function(d) { + return [ + d.date.getFullYear() + '' + utils.padNum(d.date.getMonth() + 1) + '' + utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(panchayatResponse) + .map(function(d) { + return d.values; + }) + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); + + var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn']; + + var data = { + 'overview': { + 'current_total': current_total, + 'delayed_total': delayed_total, + 'days_to_payment': days_to_payment, + 'cards_total': cards.length + }, + 'cards': cards, + 'block_performance': blockPerformance, + 'panchayat_performance': panchayatPerformance, + 'config': { + 'headers': headers, + labels: [ + 'Date', + 'Muster roll closure to muster roll entry', + 'Muster roll entry to wage list generation', + 'Wage list generation to wage list sent', + 'Wage list sent to FTO generation', + 'FTO generation to first signature', + 'First signature to second signature', + 'Second signature to processed by bank', + 'Total Transactions' + ], + }, + 'contact': { + 'phone': contactResponse[0].phone, + 'email': contactResponse[0].email, + 'subject': contactResponse[0].subject + } + }; + + reply(data); + + } + } + }); } }; diff --git a/app/controllers/monitor/analysis.js b/app/controllers/monitor/analysis.js deleted file mode 100644 index 44fcc0fe..00000000 --- a/app/controllers/monitor/analysis.js +++ /dev/null @@ -1,78 +0,0 @@ -'use strict'; - -var queries = require('../../helpers/queries'); - -exports.showPage = { - handler: function(request, reply) { - return reply.view('monitor/analysis', null, { - layout: 'monitor' - }); - } -}; - -exports.getData = { - handler: function(request, reply) { - - var sequelize = request.server.plugins.sequelize.db.sequelize; - var queryString = queries.outcomes(); - - sequelize.query(queryString, { - type: sequelize.QueryTypes.SELECT - }).then(function(data) { - - var results = []; - var outcomes = data[0]; - var treatments = data[1]; - var summary = data[2]; - var arms = data[3]; - var arm_summary = data[4]; - - for (var index in outcomes) { - - var result = { - treatment: [], - control: [], - arm_1: [], - arm_2: [], - arm_3: [] - }; - result.label = outcomes[index].label; - result.name = outcomes[index].outcome; - for (var treatment_index in treatments) { - treatments[treatment_index].value = treatments[treatment_index].mean; - if (treatments[treatment_index].outcome === outcomes[index].outcome && treatments[treatment_index].treatment === 1) { - result.treatment.push(treatments[treatment_index]); - } - if (treatments[treatment_index].outcome === outcomes[index].outcome && treatments[treatment_index].treatment === 0) { - result.control.push(treatments[treatment_index]); - } - } - for (var arm_index in arms) { - arms[arm_index].value = arms[arm_index].mean; - if (arms[arm_index].outcome === outcomes[index].outcome && arms[arm_index].arm === 1) { - result.arm_1.push(arms[arm_index]); - } - if (arms[arm_index].outcome === outcomes[index].outcome && arms[arm_index].arm === 2) { - result.arm_2.push(arms[arm_index]); - } - if (arms[arm_index].outcome === outcomes[index].outcome && arms[arm_index].arm === 3) { - result.arm_3.push(arms[arm_index]); - } - } - for (var stat_index in summary) { - if (summary[stat_index].outcome === outcomes[index].outcome) { - result.summary = summary[stat_index]; - } - } - for (var arm_stat_index in arm_summary) { - if (arm_summary[arm_stat_index].outcome === outcomes[index].outcome) { - result.arm_summary = arm_summary[arm_stat_index]; - } - } - results.push(result); - } - - reply(results); - }); - } -}; diff --git a/app/controllers/monitor/server.js b/app/controllers/monitor/server.js deleted file mode 100644 index a1c57533..00000000 --- a/app/controllers/monitor/server.js +++ /dev/null @@ -1,57 +0,0 @@ -'use strict'; - -var path = require('path'); -var readline = require('readline'); -var fs = require('fs'); - -exports.showPage = { - handler: function(request, reply) { - return reply.view('monitor/server', null, { - layout: 'monitor' - }); - } -}; - -exports.getData = { - handler: function(request, reply) { - - var stats = []; - var statPath = path.resolve(__dirname + '/../../../logs/stats/stats.log'); - var lineReader = readline.createInterface({ - input: fs.createReadStream(statPath) - }); - - lineReader.on('line', function(line) { - stats.push(JSON.parse(line)); - }); - - lineReader.on('close', function() { - reply(stats); - }); - - } -}; - -exports.getPageLoadData = { - handler: function(request, reply) { - var analytics = request.server.plugins.ga.analytics; - var jwtClient = request.server.plugins.ga.jwtClient; - jwtClient.authorize(function(err, tokens) { - if (err) { - return; - } - - analytics.data.ga.get({ - auth: jwtClient, - 'ids': 'ga:73657543', - 'metrics': 'ga:avgPageLoadTime', - 'dimensions':'ga:date,ga:pagePath', - 'start-date': '2015-01-01', - 'end-date': '2016-01-16' - }, function(err, response) { - reply(response); - }); - - }); - } -}; diff --git a/app/controllers/monitor/user.js b/app/controllers/monitor/user.js deleted file mode 100644 index a1916609..00000000 --- a/app/controllers/monitor/user.js +++ /dev/null @@ -1,49 +0,0 @@ -'use strict'; -var d3 = require('d3'); - -exports.showPage = { - handler: function(request, reply) { - return reply.view('monitor/user', null, { - layout: 'monitor' - }); - } -}; - -exports.getData = { - handler: function(request, reply) { - - var analytics = request.server.plugins.ga.analytics; - var jwtClient = request.server.plugins.ga.jwtClient; - jwtClient.authorize(function(err, tokens) { - if (err) { - return; - } - console.log('authenticated'); - analytics.data.ga.get({ - auth: jwtClient, - 'ids': 'ga:114514109', - 'metrics': 'ga:users,ga:sessionsPerUser,ga:pageviews,ga:sessions,ga:avgSessionDuration', - 'dimensions': 'ga:date', - 'start-date': '2015-12-18', - 'end-date': '2016-01-17' - }, function(err, response) { - console.log(response); - reply(response); - }); - - // analytics.data.ga.get({ - // auth: jwtClient, - // 'ids': 'ga:73657543', - // 'metrics': 'ga:pageviews,ga:avgTimeOnPage', - // 'dimensions':'ga:date,ga:pagePath', - // 'start-date': '2015-01-01', - // 'end-date': '2015-03-09' - // }, function(err, response) { - // console.log(response); - // }); - - }); - - - } -}; diff --git a/app/controllers/musters/cards.js b/app/controllers/musters/cards.js index c44a1be2..b37d71d9 100644 --- a/app/controllers/musters/cards.js +++ b/app/controllers/musters/cards.js @@ -1,10 +1,10 @@ 'use strict'; -var Queries = require('../../helpers/queries'); -var OverviewParser = require('../../helpers/overview_parser'); -var Translate = require('../../templates/helpers/t'); -var utils = require('../../helpers/utils'); -var d3 = require(d3); +const Queries = require('../../helpers/queries'); +const OverviewParser = require('../../helpers/overview_parser'); +const Translate = require('../../templates/helpers/t'); +const Utils = require('../../helpers/utils'); +const D3 = require('d3'); exports.showPage = { handler: function(request, reply) { @@ -24,11 +24,11 @@ exports.getData = { type: sequelize.QueryTypes.SELECT }).then(function(rows) { - var overviewResponse = utils.flatten(rows[0]); + var overviewResponse = Utils.flatten(rows[0]); - var tilesResponse = utils.flatten(rows[1]); + var tilesResponse = Utils.flatten(rows[1]); - var stateResponse = utils.flatten(rows[2]); + var stateResponse = Utils.flatten(rows[2]); // Parse the overview response var current_total = overviewResponse[0].current_total; @@ -38,7 +38,7 @@ exports.getData = { var state_code = stateResponse[0].state_code; if (role === 'block') { - var tiles = d3.nest() + var tiles = D3.nest() .key(function(d) { return d.staff_id; }) @@ -46,33 +46,31 @@ exports.getData = { return { 'name': v[0].name, 'staff_id': v[0].staff_id, - 'designation': utils.getDesignation(v[0].task_assign,state_code), - 'mobile':v[0].mobile_no, - 'block_name':v[0].block_name, - 'current_total':v[0].current_total, - 'delayed_total':v[0].delayed_total, - 'delayed_musters': v.filter(function(d) { return d.type==='delayed_musters'; }).map(function(d) { - return [ - { - 'msr_no':d.msr_no, - 'panchayat_name':d.panchayat_name, - 'work_name':d.work_name, - 'work_code':d.work_code, - 'closure_date':d.end_date, - 'days_pending':d.days_pending - } - ]; + 'designation': Utils.getDesignation(v[0].task_assign, state_code), + 'mobile': v[0].mobile_no, + 'block_name': v[0].block_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'delayed_musters': v.filter(function(d) { + return d.type === 'delayed_musters'; }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date, + 'days_pending': d.days_pending + }]; }), - 'current_musters': v.filter(function(d) { return d.type==='current_musters'; }).map(function(d) { - return [ - { - 'msr_no':d.msr_no, - 'panchayat_name':d.panchayat_name, - 'work_name':d.work_name, - 'work_code':d.work_code, - 'closure_date':d.end_date - } - ]; + 'current_musters': v.filter(function(d) { + return d.type === 'current_musters'; }).map(function(d) { + return [{ + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date + }]; }) }; }) @@ -88,9 +86,9 @@ exports.getData = { var final_dict = { 'overview': { - 'current_total':current_total, - 'delayed_total':delayed_total, - 'days_to_payment':days_to_payment, + 'current_total': current_total, + 'delayed_total': delayed_total, + 'days_to_payment': days_to_payment, 'tiles_total': tiles.length }, 'tiles': tiles, diff --git a/app/controllers/users/settings-account.js b/app/controllers/users/settings-account.js index 1313235b..28f149d4 100644 --- a/app/controllers/users/settings-account.js +++ b/app/controllers/users/settings-account.js @@ -1,7 +1,7 @@ 'use strict'; -var Joi = require('joi'); -var crypto = require('crypto'); +const Joi = require('joi'); +const Crypto = require('crypto'); exports.showEditAccount = { description: 'Show Edit account settings', @@ -43,12 +43,12 @@ exports.postChangePassword = { User.findOne({ where: { username: request.auth.credentials.username, - password: crypto.createHash('md5').update(request.payload.oldPassword).digest('hex') + password: Crypto.createHash('md5').update(request.payload.oldPassword).digest('hex') } }).then(function(user) { if (user) { user.update({ - password: crypto.createHash('md5').update(request.payload.newPassword).digest('hex') + password: Crypto.createHash('md5').update(request.payload.newPassword).digest('hex') }).then(function() { request.session.flash('success', 'Password changed successfully. Please login with new password'); request.auth.session.clear(); diff --git a/app/controllers/users/settings-profile.js b/app/controllers/users/settings-profile.js index 028ad3eb..4e617b6f 100644 --- a/app/controllers/users/settings-profile.js +++ b/app/controllers/users/settings-profile.js @@ -1,6 +1,6 @@ 'use strict'; -var Joi = require('joi'); +const Joi = require('joi'); exports.showEditProfile = { description: 'Show Edit profile settings', diff --git a/app/helpers/notifier.js b/app/helpers/notifier.js deleted file mode 100644 index 54f402ba..00000000 --- a/app/helpers/notifier.js +++ /dev/null @@ -1,42 +0,0 @@ -'use strict'; - -var Translate = require('../templates/helpers/t'); - - -exports.message = function(n, request) { - var msg = ''; - - if (n.dataValues.notification_type === 1) { - var region_name = n.dataValues.region_name; - var total_transactions = n.dataValues.total_transactions; - var monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; - var batch_date = n.dataValues.batch_date.getDate() + ' ' + monthNames[n.dataValues.batch_date.getMonth()] + ' ' + n.dataValues.batch_date.getFullYear(); - var notification_sub_text = Translate('/notifications/message/1', request.auth.credentials); - - if (request.auth.credentials.lang === 'en_US') { - msg = region_name + notification_sub_text[0] + total_transactions + notification_sub_text[1] + batch_date + notification_sub_text[2]; - } else if (request.auth.credentials.lang === 'hi') { - msg = region_name + notification_sub_text[0] + batch_date + notification_sub_text[1] + total_transactions + notification_sub_text[2]; - } - - } - - if (n.dataValues.notification_type === 2) { - var days_to_payment = n.dataValues.days_to_payment; - var notification_sub_text = Translate('/notifications/message/2/main', request.auth.credentials); - var comparison_array = Translate('/notifications/message/2/comparison', request.auth.credentials); - - if (days_to_payment > 15) { - var comparison_text = comparison_array[0]; - } else if (days_to_payment === 15) { - var comparison_text = comparison_array[1]; - } else if (days_to_payment < 15) { - var comparison_text = comparison_array[2]; - } - - msg = notification_sub_text[0] + days_to_payment + notification_sub_text[1] + comparison_text + notification_sub_text[2]; - - } - - return msg; -} diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index 53f192ba..8346e008 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -1,14 +1,14 @@ 'use strict'; -var Utils = require('./utils'); +const Utils = require('./utils'); exports.block = function(rows) { -} +}; exports.district = function(rows) { -} +}; diff --git a/app/helpers/utils.js b/app/helpers/utils.js index 2c2a5503..777d8772 100644 --- a/app/helpers/utils.js +++ b/app/helpers/utils.js @@ -1,6 +1,6 @@ 'use strict'; -var d3 = require('d3'); +const D3 = require('d3'); exports.padNum = function(num) { var str = num.toString(); @@ -18,7 +18,7 @@ exports.flatten = function(obj) { }; exports.nestEmpMapping = function(obj) { - return d3.nest() + return D3.nest() .key(function(d) { return d.region_code; }) @@ -29,7 +29,7 @@ exports.nestEmpMapping = function(obj) { }; exports.nestEmpStats = function(obj) { - return d3.nest() + return D3.nest() .key(function(d) { return d.staff_id; }) @@ -42,17 +42,16 @@ exports.nestEmpStats = function(obj) { .map(exports.flatten(obj)); }; -exports.getDesignation = function(task_assign,state_code) { +exports.getDesignation = function(task_assign, state_code) { var designationLookup = { - 17:'SE', - 33:'TA', - 34:'JE' + 17: 'SE', + 33: 'TA', + 34: 'JE' }; if (task_assign === 'TA') { return designationLookup[state_code]; - } - else { + } else { return task_assign; } -} +}; From 7631819295e1e7a625ed527ca4cc6743c13414ff Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Tue, 2 Aug 2016 13:52:56 +0530 Subject: [PATCH 025/314] Cleanup notification api code --- app/controllers/api/notifications.js | 62 ---------------------------- app/routes/api.js | 11 +---- 2 files changed, 1 insertion(+), 72 deletions(-) delete mode 100644 app/controllers/api/notifications.js diff --git a/app/controllers/api/notifications.js b/app/controllers/api/notifications.js deleted file mode 100644 index 8cdbb2b7..00000000 --- a/app/controllers/api/notifications.js +++ /dev/null @@ -1,62 +0,0 @@ -'use strict'; - -var Joi = require('joi'); -var _ = require('lodash'); -var Notifier = require('../../helpers/notifier'); - -exports.showUnreadNotifications = { - description: 'Show unread notifications', - handler: function(request, reply) { - - var db = request.server.plugins.sequelize.db; - var notifications = request.server.plugins.sequelize.db.notifications; - - notifications.findAll({ - where: { - user_id: request.auth.credentials.id, - viewed: 0 - } - - }).then(function(unread) { - - unread.forEach(function(n) { - n.dataValues.msg = Notifier.message(n, request); - }); - - notifications.update({ - viewed: 1 - }, { - where: { - user_id: request.auth.credentials.id, - viewed: 0 - } - }); - reply(unread); - }); - - } -}; - -exports.showReadNotifications = { - description: 'Show notifications', - handler: function(request, reply) { - - var db = request.server.plugins.sequelize.db; - var notifications = request.server.plugins.sequelize.db.notifications; - - notifications.findAll({ - where: { - user_id: request.auth.credentials.id, - viewed: 1 - } - }).then(function(read) { - - read.forEach(function(n) { - n.dataValues.msg = Notifier.message(n, request); - }); - - reply(read); - }); - - } -}; diff --git a/app/routes/api.js b/app/routes/api.js index b381d5da..395fe9fa 100644 --- a/app/routes/api.js +++ b/app/routes/api.js @@ -8,8 +8,7 @@ exports.register = function(plugin, options, next) { logout: require('../controllers/api/logout'), cards: require('../controllers/api/cards'), profile: require('../controllers/api/profile'), - translate: require('../controllers/api/translate'), - notifications: require('../controllers/api/notifications') + translate: require('../controllers/api/translate') } }; @@ -36,14 +35,6 @@ exports.register = function(plugin, options, next) { method: 'GET', path: '/api/translate', config: Controllers.api.translate.getData - }, { - method: 'GET', - path: '/api/notifications/unread', - config: Controllers.api.notifications.showUnreadNotifications - }, { - method: 'GET', - path: '/api/notifications/read', - config: Controllers.api.notifications.showReadNotifications } ]); From 03aea54523836f03445f926f0ede27da10560b30 Mon Sep 17 00:00:00 2001 From: edodge Date: Tue, 2 Aug 2016 13:55:27 +0530 Subject: [PATCH 026/314] Add panchayat list to paydash chart response (block version) --- app/controllers/performance/overview.js | 5 ++--- app/helpers/overview_parser.js | 6 ++++++ app/helpers/queries.js | 4 +++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/controllers/performance/overview.js b/app/controllers/performance/overview.js index bb42e3bd..62fe336e 100644 --- a/app/controllers/performance/overview.js +++ b/app/controllers/performance/overview.js @@ -22,14 +22,13 @@ exports.getData = { type: sequelize.QueryTypes.SELECT }).then(function(rows) { - var final_dict; if (role === 'block') { - final_dict = OverviewParser.block(rows); + var final_dict = OverviewParser.block(rows); } if (role === 'district') { - final_dict = OverviewParser.district(rows); + var final_dict = OverviewParser.district(rows); } final_dict.config = { diff --git a/app/helpers/overview_parser.js b/app/helpers/overview_parser.js index efe98dda..a68bbfef 100644 --- a/app/helpers/overview_parser.js +++ b/app/helpers/overview_parser.js @@ -98,7 +98,13 @@ exports.block = function(rows) { }) }; + // Process list of panchayat names and codes + var panchayatResponse = Utils.flatten(rows[4]); + final_dict.panchayats = panchayatResponse; + final_dict.region_name = blockName; + + return final_dict; } diff --git a/app/helpers/queries.js b/app/helpers/queries.js index ae247536..8a4beaa1 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -5,7 +5,9 @@ exports.overviewPerformance = function(REGION_CODE, ROLE) { return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code in (SELECT b.state_code FROM blocks b WHERE b.block_code ='" + REGION_CODE + "') GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + "SELECT district_code,district_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM district_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.district_code in (SELECT b.district_code FROM blocks b WHERE b.block_code ='" + REGION_CODE + "') GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + "SELECT block_code,block_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code ='" + REGION_CODE + "' GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + - "SELECT block_code,block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,0) mrc_mre,ROUND(mre_wlg_mean,0) mre_wlg,ROUND(wlg_wls_mean,0) wlg_wls,ROUND(wls_fto_mean,0) wls_fto,ROUND(fto_firstsign_mean,0) fto_sn1,ROUND(firstsign_secondsign_mean,0) sn1_sn2,ROUND(secondsign_processed_mean,0) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code ='" + REGION_CODE + "' ORDER BY date;"; + "SELECT block_code,block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,0) mrc_mre,ROUND(mre_wlg_mean,0) mre_wlg,ROUND(wlg_wls_mean,0) wlg_wls,ROUND(wls_fto_mean,0) wls_fto,ROUND(fto_firstsign_mean,0) fto_sn1,ROUND(firstsign_secondsign_mean,0) sn1_sn2,ROUND(secondsign_processed_mean,0) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code ='" + REGION_CODE + "' ORDER BY date;" + + "SELECT panchayat_code,panchayat_name FROM panchayats WHERE block_code = REGION_CODE;"; + } else if (ROLE === 'district') { return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code in (SELECT b.state_code FROM districts b WHERE b.district_code ='" + REGION_CODE + "') GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + "SELECT district_code,district_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM district_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.district_code='" + REGION_CODE + "' GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + From aefe116d8dd82fc9ddb1e2acc6f2174a8eb90d37 Mon Sep 17 00:00:00 2001 From: edodge Date: Wed, 3 Aug 2016 16:59:25 +0530 Subject: [PATCH 027/314] Rename controller and helper files. Create block and district overview controller/queries. --- app/controllers/api/cards.js | 6 +- app/controllers/overview/overview.js | 34 +++++ app/helpers/overview_parser.js | 194 +++------------------------ app/helpers/paydroid_parser.js | 68 +++++----- app/helpers/performance_parser.js | 183 +++++++++++++++++++++++++ app/helpers/queries.js | 55 +++----- 6 files changed, 292 insertions(+), 248 deletions(-) create mode 100644 app/controllers/overview/overview.js create mode 100644 app/helpers/performance_parser.js diff --git a/app/controllers/api/cards.js b/app/controllers/api/cards.js index 8b1c9f3a..4b02cb43 100644 --- a/app/controllers/api/cards.js +++ b/app/controllers/api/cards.js @@ -1,7 +1,7 @@ 'use strict'; -var Queries = require('../../helpers/queries'); -var Parser = require('../../helpers/paydroid_parser'); +const Queries = require('../../helpers/queries'); +const Parser = require('../../helpers/paydroid_parser'); exports.getData = { plugins: { @@ -17,7 +17,7 @@ exports.getData = { var role = request.auth.credentials.role; var version = request.pre.apiVersion; - var queryString = Queries.cards(userId, role, version); + var queryString = Queries.paydroid(userId, role, version); // API CODE sequelize.query(queryString, { diff --git a/app/controllers/overview/overview.js b/app/controllers/overview/overview.js new file mode 100644 index 00000000..fed30aa4 --- /dev/null +++ b/app/controllers/overview/overview.js @@ -0,0 +1,34 @@ +'use strict'; + +const Queries = require('../../helpers/queries'); +const OverviewParser = require('../../helpers/overview_parser'); +const Translate = require('../../templates/helpers/t'); + +exports.showPage = { + handler: function(request, reply) { + return reply.view('overview/overview'); + } +}; + +exports.getData = { + handler: function(request, reply) { + + var sequelize = request.server.plugins.sequelize.db.sequelize; + + var role = request.auth.credentials.role; + var userId = request.auth.credentials.id; + var queryString = Queries.overview(userId, role); + + sequelize.query(queryString, { + type: sequelize.QueryTypes.SELECT + }).then(function(rows) { + + // Database query takes the role as an input (district or block). Parser returns generic "region_code", "region_name" keys. + + var data = OverviewParser.parser(rows); + + reply(data); + + }); + } +}; diff --git a/app/helpers/overview_parser.js b/app/helpers/overview_parser.js index a68bbfef..8a6311a7 100644 --- a/app/helpers/overview_parser.js +++ b/app/helpers/overview_parser.js @@ -1,183 +1,33 @@ 'use strict'; -var Utils = require('./utils'); +const D3 = require('D3'); -var final_dict = {}; +exports.parser = function(rows) { -final_dict.monthwise = {}; -final_dict.datewise = {}; - -exports.block = function(rows) { - - // Process state data - var stateResponse = Utils.flatten(rows[0]); - var stateName = stateResponse[0].state_name; - var stateCode = stateResponse[0].state_code; - - final_dict.monthwise.state = { - 'state_code': stateCode, - 'state_name': stateName, - 'data': stateResponse.map(function(d) { - return [ - d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - - // Process district data - var districtResponse = Utils.flatten(rows[1]); - var districtName = districtResponse[0].district_name; - var districtCode = districtResponse[0].district_code; - final_dict.monthwise.district = { - 'district_code': districtCode, - 'district_name': districtName, - 'data': districtResponse.map(function(d) { - return [ - d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; + var overviewResponse = D3.values(rows[0]); + var overview = D3.nest() + .key(function(d) { + return d.region_code; }) - }; - - // Process block data for bottom chart (grouped by month) - var blockResponse = Utils.flatten(rows[2]); - var blockName = blockResponse[0].block_name; - var blockCode = blockResponse[0].block_code; - final_dict.monthwise.block = { - 'block_code': blockCode, - 'block_name': blockName, - 'data': blockResponse.map(function(d) { - return [ - d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - - // Process block data for top chart (group by date) - var blockResponse = Utils.flatten(rows[3]); - var blockName = blockResponse[0].block_name; - var blockCode = blockResponse[0].block_code; - final_dict.datewise.block = { - 'block_code': blockCode, - 'block_name': blockName, - 'data': blockResponse.map(function(d) { - return [ - d.date.getFullYear() + '' + Utils.padNum(d.date.getMonth() + 1) + '' + Utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; + .rollup(function(v) { + return { + 'region_code': v[0].region_code, + 'region_name': v[0].region_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'days_to_payment': v[0].days_to_payment + } }) - }; + .entries(overviewResponse) + .map(function(d) { + return d.values; + }); - // Process list of panchayat names and codes - var panchayatResponse = Utils.flatten(rows[4]); - final_dict.panchayats = panchayatResponse; - - final_dict.region_name = blockName; - - - return final_dict; -} - -exports.district = function(rows) { - - - // process state data - var stateResponse = Utils.flatten(rows[0]); - var stateName = stateResponse[0].state_name; - var stateCode = stateResponse[0].state_code; - - final_dict.monthwise.state = { - 'state_code': stateCode, - 'state_name': stateName, - 'data': stateResponse.map(function(d) { - return [ - d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) + var data = { + 'overview': overview }; - // Process district data for bottom chart (monthwise data) - var districtResponse = Utils.flatten(rows[1]); - var districtName = districtResponse[0].district_name; - var districtCode = districtResponse[0].district_code; - final_dict.monthwise.district = { - 'district_code': districtCode, - 'district_name': districtName, - 'data': districtResponse.map(function(d) { - return [ - d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; + return data; - // Process district data for top chart (datewise data) - var districtResponse = Utils.flatten(rows[2]); - var districtName = districtResponse[0].district_name; - var districtCode = districtResponse[0].district_code; - final_dict.datewise.district = { - 'district_code': districtCode, - 'district_name': districtName, - 'data': districtResponse.map(function(d) { - return [ - d.date.getFullYear() + '' + Utils.padNum(d.date.getMonth() + 1) + '' + Utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; +}; - final_dict.region_name = districtName; - return final_dict; -} diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index 73ae57ee..1d0a0ca7 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -1,34 +1,34 @@ 'use strict'; -var d3 = require('d3'); +const D3 = require('D3'); const Utils = require('./utils'); exports.v1 = function(rows) { - var overviewResponse = d3.values(rows[0]); + var overviewResponse = D3.values(rows[0]); - var cardsResponse = d3.values(rows[1]); + var cardsResponse = D3.values(rows[1]); - var blockResponse = d3.values(rows[2]); + var blockResponse = D3.values(rows[2]); - var panchayatResponse = d3.values(rows[3]); + var panchayatResponse = D3.values(rows[3]); - var notificationsResponse = d3.values(rows[4]); + var notificationsResponse = D3.values(rows[4]); - var stateResponse = d3.values(rows[5]); + var stateResponse = D3.values(rows[5]); - var contactResponse = d3.values(rows[6]); + var contactResponse = D3.values(rows[6]); // Parse the overview response var current_total = overviewResponse[0].current_total; var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].time_to_payment; + var days_to_payment = overviewResponse[0].days_to_payment; var total_transactions = overviewResponse[0].total_transactions; var state_code = stateResponse[0].state_code; // Nest the cards response and include the overview stats - var cards = d3.nest() + var cards = D3.nest() .key(function(d) { return d.staff_id; }) @@ -72,7 +72,7 @@ exports.v1 = function(rows) { }); // Nest the block response - var blockPerformance = d3.nest() + var blockPerformance = D3.nest() .key(function(d) { return d.block_code; }) @@ -109,7 +109,7 @@ exports.v1 = function(rows) { // Nest the panchayat response - var panchayatPerformance = d3.nest() + var panchayatPerformance = D3.nest() .key(function(d) { return d.panchayat_code; }) @@ -189,27 +189,27 @@ exports.v2 = function(rows, role) { function parse_block(rows) { - var overviewResponse = d3.values(rows[0]); + var overviewResponse = D3.values(rows[0]); - var cardsResponse = d3.values(rows[1]); + var cardsResponse = D3.values(rows[1]); - var blockResponse = d3.values(rows[2]); + var blockResponse = D3.values(rows[2]); - var panchayatResponse = d3.values(rows[3]); + var panchayatResponse = D3.values(rows[3]); - var stateResponse = d3.values(rows[4]); + var stateResponse = D3.values(rows[4]); - var contactResponse = d3.values(rows[5]); + var contactResponse = D3.values(rows[5]); // Parse the overview response var current_total = overviewResponse[0].current_total; var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].time_to_payment; + var days_to_payment = overviewResponse[0].days_to_payment; var state_code = stateResponse[0].state_code; // Nest the cards response and include the overview stats - var cards = d3.nest() + var cards = D3.nest() .key(function(d) { var key = d.staff_id + d.block_code; return key; @@ -255,7 +255,7 @@ exports.v2 = function(rows, role) { // Nest the block response - var blockPerformance = d3.nest() + var blockPerformance = D3.nest() .key(function(d) { return d.block_code; }) @@ -292,7 +292,7 @@ exports.v2 = function(rows, role) { // Nest the panchayat response - var panchayatPerformance = d3.nest() + var panchayatPerformance = D3.nest() .key(function(d) { return d.panchayat_code; }) @@ -366,29 +366,29 @@ exports.v2 = function(rows, role) { function parse_district(rows) { - var overviewResponse = d3.values(rows[0]); + var overviewResponse = D3.values(rows[0]); - var cardsResponse = d3.values(rows[1]); + var cardsResponse = D3.values(rows[1]); - var districtResponse = d3.values(rows[2]); + var districtResponse = D3.values(rows[2]); - var blockResponse = d3.values(rows[3]); + var blockResponse = D3.values(rows[3]); - var panchayatResponse = d3.values(rows[4]); + var panchayatResponse = D3.values(rows[4]); - var stateResponse = d3.values(rows[5]); + var stateResponse = D3.values(rows[5]); - var contactResponse = d3.values(rows[6]); + var contactResponse = D3.values(rows[6]); // Parse the overview response var current_total = overviewResponse[0].current_total; var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].time_to_payment; + var days_to_payment = overviewResponse[0].days_to_payment; var state_code = stateResponse[0].state_code; // Nest the cards response and include the overview stats - var cards = d3.nest() + var cards = D3.nest() .key(function(d) { return d.block_code; }) @@ -423,7 +423,7 @@ exports.v2 = function(rows, role) { }); // Nest the district response - var districtPerformance = d3.nest() + var districtPerformance = D3.nest() .key(function(d) { return d.district_code; }) @@ -460,7 +460,7 @@ exports.v2 = function(rows, role) { // Nest the block response - var blockPerformance = d3.nest() + var blockPerformance = D3.nest() .key(function(d) { return d.block_code; }) @@ -497,7 +497,7 @@ exports.v2 = function(rows, role) { // Nest the panchayat response - var panchayatPerformance = d3.nest() + var panchayatPerformance = D3.nest() .key(function(d) { return d.panchayat_code; }) diff --git a/app/helpers/performance_parser.js b/app/helpers/performance_parser.js new file mode 100644 index 00000000..a68bbfef --- /dev/null +++ b/app/helpers/performance_parser.js @@ -0,0 +1,183 @@ +'use strict'; + +var Utils = require('./utils'); + +var final_dict = {}; + +final_dict.monthwise = {}; +final_dict.datewise = {}; + +exports.block = function(rows) { + + // Process state data + var stateResponse = Utils.flatten(rows[0]); + var stateName = stateResponse[0].state_name; + var stateCode = stateResponse[0].state_code; + + final_dict.monthwise.state = { + 'state_code': stateCode, + 'state_name': stateName, + 'data': stateResponse.map(function(d) { + return [ + d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + + // Process district data + var districtResponse = Utils.flatten(rows[1]); + var districtName = districtResponse[0].district_name; + var districtCode = districtResponse[0].district_code; + final_dict.monthwise.district = { + 'district_code': districtCode, + 'district_name': districtName, + 'data': districtResponse.map(function(d) { + return [ + d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + + // Process block data for bottom chart (grouped by month) + var blockResponse = Utils.flatten(rows[2]); + var blockName = blockResponse[0].block_name; + var blockCode = blockResponse[0].block_code; + final_dict.monthwise.block = { + 'block_code': blockCode, + 'block_name': blockName, + 'data': blockResponse.map(function(d) { + return [ + d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + + // Process block data for top chart (group by date) + var blockResponse = Utils.flatten(rows[3]); + var blockName = blockResponse[0].block_name; + var blockCode = blockResponse[0].block_code; + final_dict.datewise.block = { + 'block_code': blockCode, + 'block_name': blockName, + 'data': blockResponse.map(function(d) { + return [ + d.date.getFullYear() + '' + Utils.padNum(d.date.getMonth() + 1) + '' + Utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + + // Process list of panchayat names and codes + var panchayatResponse = Utils.flatten(rows[4]); + final_dict.panchayats = panchayatResponse; + + final_dict.region_name = blockName; + + + return final_dict; +} + +exports.district = function(rows) { + + + // process state data + var stateResponse = Utils.flatten(rows[0]); + var stateName = stateResponse[0].state_name; + var stateCode = stateResponse[0].state_code; + + final_dict.monthwise.state = { + 'state_code': stateCode, + 'state_name': stateName, + 'data': stateResponse.map(function(d) { + return [ + d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + + // Process district data for bottom chart (monthwise data) + var districtResponse = Utils.flatten(rows[1]); + var districtName = districtResponse[0].district_name; + var districtCode = districtResponse[0].district_code; + final_dict.monthwise.district = { + 'district_code': districtCode, + 'district_name': districtName, + 'data': districtResponse.map(function(d) { + return [ + d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + + // Process district data for top chart (datewise data) + var districtResponse = Utils.flatten(rows[2]); + var districtName = districtResponse[0].district_name; + var districtCode = districtResponse[0].district_code; + final_dict.datewise.district = { + 'district_code': districtCode, + 'district_name': districtName, + 'data': districtResponse.map(function(d) { + return [ + d.date.getFullYear() + '' + Utils.padNum(d.date.getMonth() + 1) + '' + Utils.padNum(d.date.getDate()), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + + final_dict.region_name = districtName; + return final_dict; +} diff --git a/app/helpers/queries.js b/app/helpers/queries.js index 8a4beaa1..dcc0e4bc 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -1,6 +1,6 @@ 'use strict'; -exports.overviewPerformance = function(REGION_CODE, ROLE) { +exports.performance = function(REGION_CODE, ROLE) { if (ROLE === 'block') { return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code in (SELECT b.state_code FROM blocks b WHERE b.block_code ='" + REGION_CODE + "') GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + "SELECT district_code,district_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM district_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.district_code in (SELECT b.district_code FROM blocks b WHERE b.block_code ='" + REGION_CODE + "') GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + @@ -16,34 +16,21 @@ exports.overviewPerformance = function(REGION_CODE, ROLE) { }; -exports.discretePerformance = function(REGION_CODE, ROLE) { +exports.cards = function(REGION_CODE, ROLE) { if (ROLE === 'block') { - return "SELECT block_name AS region_name FROM blocks WHERE block_code = '" + REGION_CODE + "';" + - "SELECT panchayat_code AS region_code,panchayat_name AS region_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,0) mrc_mre,ROUND(mre_wlg_mean,0) mre_wlg,ROUND(wlg_wls_mean,0) wlg_wls,ROUND(wls_fto_mean,0) wls_fto,ROUND(fto_firstsign_mean,0) fto_sn1,ROUND(firstsign_secondsign_mean,0) sn1_sn2,ROUND(secondsign_processed_mean,0) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code ='" + REGION_CODE + "' ORDER BY panchayat_code, date;" + - "SELECT staff_id, name, task_assign, mobile_no, map_location, mapped_panchayat_name FROM employees WHERE task_assign IN ('TA','GRS') AND block_code = '" + REGION_CODE + "';" + - "SELECT a.panchayat_code AS region_code, b.task_assign FROM (SELECT DISTINCT panchayat_code FROM panchayat_delays_duration WHERE block_code = '" + REGION_CODE + "' AND panchayat_code <> '0000000000' AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date') a LEFT JOIN (SELECT map_location, task_assign FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign = 'TA') b ON a.panchayat_code = b.map_location;" + - "SELECT a.panchayat_code AS region_code, b.task_assign FROM (SELECT DISTINCT panchayat_code FROM panchayat_delays_duration WHERE block_code = '" + REGION_CODE + "' AND panchayat_code <> '0000000000' AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date') a LEFT JOIN (SELECT map_location, task_assign FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign = 'GRS') b ON a.panchayat_code = b.map_location;" + - "SELECT b.staff_id AS staff_id, ROUND(SUM(a.mrc_mre_mean * a.total_transactions) / SUM(a.total_transactions),0) AS step1_avg, SUM(total_transactions) as total_transactions FROM (SELECT panchayat_code, mrc_mre_mean, total_transactions FROM panchayat_delays_duration WHERE block_code = '" + REGION_CODE + "' AND panchayat_code <> '0000000000' AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions>0 AND date > sysdate()-30) a RIGHT JOIN (SELECT staff_id, map_location FROM employees WHERE task_assign='TA' AND block_code = '" + REGION_CODE + "') b ON a.panchayat_code = b.map_location GROUP BY staff_id;" + - "SELECT b.staff_id AS staff_id, ROUND(SUM(a.mrc_mre_mean * a.total_transactions) / SUM(a.total_transactions),0) AS step1_avg, SUM(total_transactions) as total_transactions FROM (SELECT panchayat_code, mrc_mre_mean, total_transactions FROM panchayat_delays_duration WHERE block_code = '" + REGION_CODE + "' AND panchayat_code <> '0000000000' AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions>0 AND date > sysdate()-30) a RIGHT JOIN (SELECT staff_id, map_location FROM employees WHERE task_assign='GRS' AND block_code = '" + REGION_CODE + "') b ON a.panchayat_code = b.map_location GROUP BY staff_id;" + - "SELECT b.staff_id AS staff_id, ROUND(SUM(a.mrc_mre_mean * a.total_transactions) / SUM(a.total_transactions),0) AS step1_avg, SUM(total_transactions) as total_transactions FROM (SELECT panchayat_code, mrc_mre_mean, total_transactions FROM panchayat_delays_duration WHERE block_code = '" + REGION_CODE + "' AND panchayat_code <> '0000000000' AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions>0 AND date > sysdate()-60) a RIGHT JOIN (SELECT staff_id, map_location FROM employees WHERE task_assign='TA' AND block_code = '" + REGION_CODE + "') b ON a.panchayat_code = b.map_location GROUP BY staff_id;" + - "SELECT b.staff_id AS staff_id, ROUND(SUM(a.mrc_mre_mean * a.total_transactions) / SUM(a.total_transactions),0) AS step1_avg, SUM(total_transactions) as total_transactions FROM (SELECT panchayat_code, mrc_mre_mean, total_transactions FROM panchayat_delays_duration WHERE block_code = '" + REGION_CODE + "' AND panchayat_code <> '0000000000' AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions>0 AND date > sysdate()-60) a RIGHT JOIN (SELECT staff_id, map_location FROM employees WHERE task_assign='GRS' AND block_code = '" + REGION_CODE + "') b ON a.panchayat_code = b.map_location GROUP BY staff_id;" + - "SELECT b.staff_id AS staff_id, ROUND(SUM(a.mrc_mre_mean * a.total_transactions) / SUM(a.total_transactions),0) AS step1_avg, SUM(total_transactions) as total_transactions FROM (SELECT panchayat_code, mrc_mre_mean, total_transactions FROM panchayat_delays_duration WHERE block_code = '" + REGION_CODE + "' AND panchayat_code <> '0000000000' AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions>0) a RIGHT JOIN (SELECT staff_id, map_location FROM employees WHERE task_assign='TA' AND block_code = '" + REGION_CODE + "') b ON a.panchayat_code = b.map_location GROUP BY staff_id;" + - "SELECT b.staff_id AS staff_id, ROUND(SUM(a.mrc_mre_mean * a.total_transactions) / SUM(a.total_transactions),0) AS step1_avg, SUM(total_transactions) as total_transactions FROM (SELECT panchayat_code, mrc_mre_mean, total_transactions FROM panchayat_delays_duration WHERE block_code = '" + REGION_CODE + "' AND panchayat_code <> '0000000000' AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions>0) a RIGHT JOIN (SELECT staff_id, map_location FROM employees WHERE task_assign='GRS' AND block_code = '" + REGION_CODE + "') b ON a.panchayat_code = b.map_location GROUP BY staff_id;" + - "SELECT a.total_panchayat_count, b.ta_panchayat_count, c.grs_panchayat_count FROM (SELECT block_code, IFNULL(count(*),0) AS total_panchayat_count FROM panchayats WHERE block_code = '" + REGION_CODE + "') a LEFT JOIN (SELECT '" + REGION_CODE + "' AS block_code, IFNULL(count(*),0) AS ta_panchayat_count FROM employees WHERE task_assign = 'TA' AND block_code = '" + REGION_CODE + "') b ON a.block_code = b.block_code LEFT JOIN (SELECT '" + REGION_CODE + "' AS block_code, IFNULL(count(*),0) AS grs_panchayat_count FROM employees WHERE task_assign = 'GRS' AND block_code = '" + REGION_CODE + "') c ON a.block_code = c.block_code;"; - } else if (ROLE === 'district') { - return "SELECT district_name AS region_name FROM districts WHERE district_code = '" + REGION_CODE + "';" + - "SELECT block_code AS region_code,block_name AS region_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,0) mrc_mre,ROUND(mre_wlg_mean,0) mre_wlg,ROUND(wlg_wls_mean,0) wlg_wls,ROUND(wls_fto_mean,0) wls_fto,ROUND(fto_firstsign_mean,0) fto_sn1,ROUND(firstsign_secondsign_mean,0) sn1_sn2,ROUND(secondsign_processed_mean,0) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code ='" + REGION_CODE + "' ORDER BY block_code, date;" + - "SELECT block_code, panchayat_code, panchayat_name FROM panchayats WHERE district_code = '" + REGION_CODE + "';"; + return "SELECT a.current_total, b.delayed_total, c.days_to_payment, c.total_transactions FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code = '" + REGION_CODE + "') a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code = '" + REGION_CODE + "') b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment, IFNULL(SUM(total_transactions),0) AS total_transactions, 1 AS merge FROM block_delays_duration WHERE block_code = '" + REGION_CODE + "' AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + + "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, a.msr_no, a.work_name, a.work_code, a.panchayat_name, a.end_date, a.days_pending, a.step, a.type FROM (SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, a.block_name, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "') a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code = '" + REGION_CODE + "') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_name, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_name, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t5') b ON a.map_location = b.panchayat_code) a LEFT JOIN (SELECT count(*) AS current_total, staff_id FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "') a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code = '" + REGION_CODE + "') b ON a.map_location = b.panchayat_code GROUP BY staff_id) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id UNION SELECT count(*) AS delayed_total, staff_id FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL);" + + "SELECT DISTINCT state_code FROM blocks WHERE block_code = '" + REGION_CODE + "';"; } +} -}; - -exports.tiles = function(REGION_CODE, ROLE) { +exports.overview = function(USER_ID, ROLE) { if (ROLE === 'block') { - return "SELECT a.current_total, b.delayed_total, c.time_to_payment, c.total_transactions FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code = '" + REGION_CODE + "') a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code = '" + REGION_CODE + "') b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment, IFNULL(SUM(total_transactions),0) AS total_transactions, 1 AS merge FROM block_delays_duration WHERE block_code = '" + REGION_CODE + "' AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + - "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, a.msr_no, a.work_name, a.work_code, a.panchayat_name, a.end_date, a.days_pending, a.step, a.type FROM (SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, a.block_name, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "') a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code = '" + REGION_CODE + "') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_name, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_name, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t5') b ON a.map_location = b.panchayat_code) a LEFT JOIN (SELECT count(*) AS current_total, staff_id FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "') a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code = '" + REGION_CODE + "') b ON a.map_location = b.panchayat_code GROUP BY staff_id) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id UNION SELECT count(*) AS delayed_total, staff_id FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL);" + - "SELECT DISTINCT state_code FROM blocks WHERE block_code = '" + REGION_CODE + "';"; + return "SELECT a.region_code, a.region_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, IFNULL(d.days_to_payment,'No Data') AS days_to_payment FROM (SELECT region_code, region_name FROM user_regions WHERE user_id='"+USER_ID+"') a LEFT JOIN (SELECT count(*) AS current_total, block_code AS region_code FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY region_code) b ON a.region_code = b.region_code LEFT JOIN (SELECT count(*) AS delayed_total, block_code AS region_code FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY region_code) c ON a.region_code = c.region_code LEFT JOIN (SELECT ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1) AS days_to_payment, block_code AS region_code FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY region_code) d ON a.region_code = d.region_code;"; + } else if (ROLE === 'district') { + return "SELECT a.region_code, a.region_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, IFNULL(d.days_to_payment,'No Data') AS days_to_payment FROM (SELECT region_code, region_name FROM user_regions WHERE user_id='"+USER_ID+"') a LEFT JOIN (SELECT count(*) AS current_total, b.district_code AS region_code FROM current_musters a RIGHT JOIN (SELECT district_code, block_code from blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code GROUP BY region_code ) b ON a.region_code = b.region_code LEFT JOIN (SELECT count(*) AS delayed_total, b.district_code AS region_code FROM delayed_musters a RIGHT JOIN (SELECT district_code, block_code from blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code GROUP BY region_code ) c ON a.region_code = c.region_code LEFT JOIN (SELECT ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1) AS days_to_payment, district_code AS region_code FROM district_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY region_code) d ON a.region_code = d.region_code;"; } + } exports.panchayatPerformance = function(REGION_CODE) { @@ -63,19 +50,9 @@ exports.outcomes = function() { "SELECT t1_mean, t2_mean, t3_mean, p_val, outcome FROM estimates_summary_arms;"; }; -exports.current_musters = function(BLOCK_CODE) { - return "SELECT IFNULL(a.name,'Unmapped') AS name, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, b.msr_no, b.work_name, b.panchayat_name FROM (SELECT * FROM employees WHERE block_code='"+BLOCK_CODE+"' AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code='"+BLOCK_CODE+"') b ON a.map_location = b.panchayat_code ORDER BY name, panchayat_code, msr_no;" + - "SELECT IFNULL(a.total_panchayat_count,0) AS total_panchayat_count, IFNULL(b.grs_panchayat_count,0) AS grs_panchayat_count FROM (SELECT block_code, count(*) AS total_panchayat_count FROM panchayats WHERE block_code = '" + BLOCK_CODE + "') a LEFT JOIN (SELECT block_code, count(*) AS grs_panchayat_count FROM employees WHERE task_assign = 'GRS' AND block_code = '" + BLOCK_CODE + "') b ON a.block_code = b.block_code;"; -}; - -exports.delayed_musters = function(BLOCK_CODE) { - return "SELECT IFNULL(a.name,'Unmapped') AS name, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, b.msr_no, b.work_name, b.panchayat_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') AS end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step FROM (SELECT * FROM employees WHERE block_code='"+BLOCK_CODE+"' AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code='"+BLOCK_CODE+"' AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT IFNULL(a.name,'Unmapped') AS name, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, b.msr_no, b.work_name, b.panchayat_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') AS end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step FROM (SELECT * FROM employees WHERE block_code='"+BLOCK_CODE+"' AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code='"+BLOCK_CODE+"' AND step='ds_t5') b ON a.map_location = b.panchayat_code UNION SELECT NULL AS name, NULL AS mobile_no, msr_no, work_name, panchayat_code, panchayat_name, DATE_FORMAT(end_date,'%d-%m-%Y') AS end_date, (datediff(CURDATE(), end_date) - CAST(REPLACE(step,'ds_t','') AS UNSIGNED)) AS days_pending, step FROM delayed_musters WHERE block_code='"+BLOCK_CODE+"' AND step NOT IN ('ds_t2','ds_t5') ORDER BY step, name, panchayat_code, msr_no;" + - "SELECT IFNULL(a.total_panchayat_count,0) AS total_panchayat_count, IFNULL(b.ta_panchayat_count,0) AS ta_panchayat_count, IFNULL(c.grs_panchayat_count,0) AS grs_panchayat_count FROM (SELECT block_code, count(*) AS total_panchayat_count FROM panchayats WHERE block_code = '" + BLOCK_CODE + "') a LEFT JOIN (SELECT block_code, count(*) AS ta_panchayat_count FROM employees WHERE task_assign = 'TA' AND block_code = '" + BLOCK_CODE + "') b ON a.block_code = b.block_code LEFT JOIN (SELECT block_code, count(*) AS grs_panchayat_count FROM employees WHERE task_assign = 'GRS' AND block_code = '" + BLOCK_CODE + "') c ON a.block_code = c.block_code;"; -}; - -exports.cards = function(USER_ID,ROLE,VERSION) { +exports.paydroid = function(USER_ID,ROLE,VERSION) { if (VERSION===1) { - return "SELECT a.current_total, b.delayed_total, c.time_to_payment, c.total_transactions FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment, IFNULL(SUM(total_transactions),0) AS total_transactions, 1 AS merge FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + + return "SELECT a.current_total, b.delayed_total, c.days_to_payment, c.total_transactions FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment, IFNULL(SUM(total_transactions),0) AS total_transactions, 1 AS merge FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + "SELECT block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY panchayat_code, date;" + @@ -84,15 +61,15 @@ exports.cards = function(USER_ID,ROLE,VERSION) { "SELECT * FROM contact;"; } else if (VERSION===2) { if (ROLE==='block') { - return "SELECT a.current_total, b.delayed_total, c.time_to_payment FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment, 1 AS merge FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + + return "SELECT a.current_total, b.delayed_total, c.days_to_payment FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment, 1 AS merge FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + "SELECT block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY panchayat_code, date;" + "SELECT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + "SELECT * FROM contact;"; } else if (ROLE=='district') { - return "SELECT a.current_total, b.delayed_total, c.time_to_payment FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT a.block_code FROM blocks a RIGHT JOIN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") b ON a.district_code = b.region_code)) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT a.block_code FROM blocks a RIGHT JOIN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") b ON a.district_code = b.region_code)) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment, 1 AS merge FROM district_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + - "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, b.time_to_payment, c.current_total, d.delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS time_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;" + + return "SELECT a.current_total, b.delayed_total, c.days_to_payment FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT a.block_code FROM blocks a RIGHT JOIN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") b ON a.district_code = b.region_code)) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT a.block_code FROM blocks a RIGHT JOIN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") b ON a.district_code = b.region_code)) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment, 1 AS merge FROM district_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + + "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, b.days_to_payment, c.current_total, d.delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;" + "SELECT district_code, district_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM district_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY district_code, date;" + "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + "SELECT district_code, block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT a.block_code FROM blocks a RIGHT JOIN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") b ON a.district_code = b.region_code) ORDER BY panchayat_code, date;" + From b7589f602aae2be20657eaec5d58a63d126d6d2c Mon Sep 17 00:00:00 2001 From: edodge Date: Wed, 3 Aug 2016 21:03:35 +0530 Subject: [PATCH 028/314] Update cards API --- app/controllers/musters/cards.js | 69 ++++++++++++++++---------------- app/helpers/queries.js | 9 ++--- 2 files changed, 38 insertions(+), 40 deletions(-) diff --git a/app/controllers/musters/cards.js b/app/controllers/musters/cards.js index b37d71d9..41ea94be 100644 --- a/app/controllers/musters/cards.js +++ b/app/controllers/musters/cards.js @@ -1,7 +1,7 @@ 'use strict'; const Queries = require('../../helpers/queries'); -const OverviewParser = require('../../helpers/overview_parser'); +const CardsParser = require('../../helpers/cards_parser'); const Translate = require('../../templates/helpers/t'); const Utils = require('../../helpers/utils'); const D3 = require('d3'); @@ -16,29 +16,27 @@ exports.getData = { handler: function(request, reply) { var sequelize = request.server.plugins.sequelize.db.sequelize; - var region_code = request.query.region_code; + var userId = request.auth.credentials.id; var role = request.auth.credentials.role; - var queryString = Queries.tiles(region_code, role); + var queryString = Queries.cards(userId, role); sequelize.query(queryString, { type: sequelize.QueryTypes.SELECT }).then(function(rows) { - var overviewResponse = Utils.flatten(rows[0]); - - var tilesResponse = Utils.flatten(rows[1]); + if (role === 'block') { - var stateResponse = Utils.flatten(rows[2]); + var cardsResponse = D3.values(rows[0]); - // Parse the overview response - var current_total = overviewResponse[0].current_total; - var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].time_to_payment; + var stateResponse = D3.values(rows[1]); - var state_code = stateResponse[0].state_code; + var state_code = stateResponse[0].state_code; - if (role === 'block') { - var tiles = D3.nest() + // Nest the cards response + var cards = D3.nest() + .key(function(d) { + return d.block_code; + }) .key(function(d) { return d.staff_id; }) @@ -52,52 +50,53 @@ exports.getData = { 'current_total': v[0].current_total, 'delayed_total': v[0].delayed_total, 'delayed_musters': v.filter(function(d) { - return d.type === 'delayed_musters'; }).map(function(d) { - return [{ + return d.type === 'delayed_musters'; + }).map(function(d) { + return { 'msr_no': d.msr_no, 'panchayat_name': d.panchayat_name, 'work_name': d.work_name, 'work_code': d.work_code, 'closure_date': d.end_date, 'days_pending': d.days_pending - }]; + }; }), 'current_musters': v.filter(function(d) { - return d.type === 'current_musters'; }).map(function(d) { - return [{ + return d.type === 'current_musters'; + }).map(function(d) { + return { 'msr_no': d.msr_no, 'panchayat_name': d.panchayat_name, 'work_name': d.work_name, 'work_code': d.work_code, 'closure_date': d.end_date - }]; + }; }) }; }) - .entries(tilesResponse) + .entries(cardsResponse) .map(function(d) { - return d.values; + return { + 'block_code': d.key, + 'cards': d.value.value + }; + }) + .map(function(d) { + return d.value; }); + + var data = { + 'cards': cards + }; + } if (role === 'district') { // } - var final_dict = { - 'overview': { - 'current_total': current_total, - 'delayed_total': delayed_total, - 'days_to_payment': days_to_payment, - 'tiles_total': tiles.length - }, - 'tiles': tiles, - 'config': { - role: role - } - }; - reply(final_dict); + reply(data); }); } }; diff --git a/app/helpers/queries.js b/app/helpers/queries.js index dcc0e4bc..3ad3f796 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -16,11 +16,10 @@ exports.performance = function(REGION_CODE, ROLE) { }; -exports.cards = function(REGION_CODE, ROLE) { +exports.cards = function(USER_ID, ROLE) { if (ROLE === 'block') { - return "SELECT a.current_total, b.delayed_total, c.days_to_payment, c.total_transactions FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code = '" + REGION_CODE + "') a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code = '" + REGION_CODE + "') b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment, IFNULL(SUM(total_transactions),0) AS total_transactions, 1 AS merge FROM block_delays_duration WHERE block_code = '" + REGION_CODE + "' AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + - "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, a.msr_no, a.work_name, a.work_code, a.panchayat_name, a.end_date, a.days_pending, a.step, a.type FROM (SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, a.block_name, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "') a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code = '" + REGION_CODE + "') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_name, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_name, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t5') b ON a.map_location = b.panchayat_code) a LEFT JOIN (SELECT count(*) AS current_total, staff_id FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "') a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code = '" + REGION_CODE + "') b ON a.map_location = b.panchayat_code GROUP BY staff_id) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id UNION SELECT count(*) AS delayed_total, staff_id FROM (SELECT * FROM employees WHERE block_code = '" + REGION_CODE + "' AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code = '" + REGION_CODE + "' AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL);" + - "SELECT DISTINCT state_code FROM blocks WHERE block_code = '" + REGION_CODE + "';"; + return "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + + "SELECT DISTINCT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"');"; } } @@ -35,7 +34,7 @@ exports.overview = function(USER_ID, ROLE) { exports.panchayatPerformance = function(REGION_CODE) { return "SELECT panchayat_name as region_name from panchayats where panchayat_code=" + REGION_CODE + ";" + - "SELECT panchayat_code AS region_code,panchayat_name AS region_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,0) mrc_mre,ROUND(mre_wlg_mean,0) mre_wlg,ROUND(wlg_wls_mean,0) wlg_wls,ROUND(wls_fto_mean,0) wls_fto,ROUND(fto_firstsign_mean,0) fto_sn1,ROUND(firstsign_secondsign_mean,0) sn1_sn2,ROUND(secondsign_processed_mean,0) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND panchayat_code ='" + REGION_CODE + "' ORDER BY panchayat_code, date;"; + "SELECT panchayat_code AS region_code,panchayat_name AS region_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,0) mrc_mre,ROUND(mre_wlg_mean,0) mre_wlg,ROUND(wlg_wls_mean,0) wlg_wls,ROUND(wls_fto_mean,0) wls_fto,ROUND(fto_firstsign_mean,0) fto_sn1,ROUND(firstsign_secondsign_mean,0) sn1_sn2,ROUND(secondsign_processed_mean,0) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND panchayat_code ='" + REGION_CODE + "' ORDER BY panchayat_code, date;"; }; exports.userBlocks = function(USER_ID) { From d9b779306b6dbf189f406fd8c2b9a5254a9cd1e9 Mon Sep 17 00:00:00 2001 From: edodge Date: Wed, 3 Aug 2016 21:52:36 +0530 Subject: [PATCH 029/314] Add PayDash card data for blocks --- app/controllers/musters/cards.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/app/controllers/musters/cards.js b/app/controllers/musters/cards.js index 41ea94be..3ce96880 100644 --- a/app/controllers/musters/cards.js +++ b/app/controllers/musters/cards.js @@ -35,8 +35,9 @@ exports.getData = { // Nest the cards response var cards = D3.nest() .key(function(d) { - return d.block_code; + return d.block_name; }) + .sortKeys(D3.descending) .key(function(d) { return d.staff_id; }) @@ -44,9 +45,8 @@ exports.getData = { return { 'name': v[0].name, 'staff_id': v[0].staff_id, - 'designation': Utils.getDesignation(v[0].task_assign, state_code), + 'designation': v[0].task_assign, 'mobile': v[0].mobile_no, - 'block_name': v[0].block_name, 'current_total': v[0].current_total, 'delayed_total': v[0].delayed_total, 'delayed_musters': v.filter(function(d) { @@ -74,15 +74,12 @@ exports.getData = { }) }; }) - .entries(cardsResponse) + .entries(data) .map(function(d) { - return { - 'block_code': d.key, - 'cards': d.value.value + return { + 'block_name': d.key, + 'cards': d.values.map(function(e) { return e.values; }) }; - }) - .map(function(d) { - return d.value; }); var data = { From dc26f4471e474a6c1043b53a9be1c395a5d802db Mon Sep 17 00:00:00 2001 From: edodge Date: Thu, 4 Aug 2016 11:55:50 +0530 Subject: [PATCH 030/314] Adding performance parser, updating queries --- .../{overview.js => performance.js} | 18 +-- app/helpers/performance_parser.js | 144 +++++++++++------- app/helpers/queries.js | 9 +- 3 files changed, 102 insertions(+), 69 deletions(-) rename app/controllers/performance/{overview.js => performance.js} (68%) diff --git a/app/controllers/performance/overview.js b/app/controllers/performance/performance.js similarity index 68% rename from app/controllers/performance/overview.js rename to app/controllers/performance/performance.js index 62fe336e..9c0be4eb 100644 --- a/app/controllers/performance/overview.js +++ b/app/controllers/performance/performance.js @@ -1,12 +1,12 @@ 'use strict'; -var Queries = require('../../helpers/queries'); -var OverviewParser = require('../../helpers/overview_parser'); -var Translate = require('../../templates/helpers/t'); +const Queries = require('../../helpers/queries'); +const PerformanceParser = require('../../helpers/performance_parser'); +const Translate = require('../../templates/helpers/t'); exports.showPage = { handler: function(request, reply) { - return reply.view('performance/overview'); + return reply.view('performance/performance'); } }; @@ -14,9 +14,9 @@ exports.getData = { handler: function(request, reply) { var sequelize = request.server.plugins.sequelize.db.sequelize; - var region_code = request.query.region_code; + var userId = request.auth.credentials.id; var role = request.auth.credentials.role; - var queryString = Queries.overviewPerformance(region_code, role); + var queryString = Queries.performance(userId, role); sequelize.query(queryString, { type: sequelize.QueryTypes.SELECT @@ -24,14 +24,14 @@ exports.getData = { if (role === 'block') { - var final_dict = OverviewParser.block(rows); + var data = PerformanceParser.block(rows); } if (role === 'district') { - var final_dict = OverviewParser.district(rows); + var data = PerformanceParser.district(rows); } - final_dict.config = { + data.config = { role: role, headers: ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn'], labels: Translate('/payment_steps_labels', request.auth.credentials), diff --git a/app/helpers/performance_parser.js b/app/helpers/performance_parser.js index a68bbfef..0c13e552 100644 --- a/app/helpers/performance_parser.js +++ b/app/helpers/performance_parser.js @@ -1,20 +1,16 @@ 'use strict'; var Utils = require('./utils'); - -var final_dict = {}; - -final_dict.monthwise = {}; -final_dict.datewise = {}; +const D3 = require('D3'); exports.block = function(rows) { // Process state data - var stateResponse = Utils.flatten(rows[0]); + var stateResponse = D3.values(rows[0]); var stateName = stateResponse[0].state_name; var stateCode = stateResponse[0].state_code; - final_dict.monthwise.state = { + var statePerformance = { 'state_code': stateCode, 'state_name': stateName, 'data': stateResponse.map(function(d) { @@ -32,11 +28,11 @@ exports.block = function(rows) { }) }; - // Process district data - var districtResponse = Utils.flatten(rows[1]); + // Process district data (can only be 1 district per block official) + var districtResponse = D3.values(rows[1]); var districtName = districtResponse[0].district_name; var districtCode = districtResponse[0].district_code; - final_dict.monthwise.district = { + var districtPerformance = { 'district_code': districtCode, 'district_name': districtName, 'data': districtResponse.map(function(d) { @@ -55,57 +51,95 @@ exports.block = function(rows) { }; // Process block data for bottom chart (grouped by month) - var blockResponse = Utils.flatten(rows[2]); + var blockResponse = D3.values(rows[2]); var blockName = blockResponse[0].block_name; var blockCode = blockResponse[0].block_code; - final_dict.monthwise.block = { - 'block_code': blockCode, - 'block_name': blockName, - 'data': blockResponse.map(function(d) { - return [ - d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - // Process block data for top chart (group by date) - var blockResponse = Utils.flatten(rows[3]); - var blockName = blockResponse[0].block_name; - var blockCode = blockResponse[0].block_code; - final_dict.datewise.block = { - 'block_code': blockCode, - 'block_name': blockName, - 'data': blockResponse.map(function(d) { - return [ - d.date.getFullYear() + '' + Utils.padNum(d.date.getMonth() + 1) + '' + Utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; + // Nest the block response (may be multiple blocks) + var blockPerformance = D3.nest() + .key(function(d) { + return d.block_code; }) - }; - - // Process list of panchayat names and codes - var panchayatResponse = Utils.flatten(rows[4]); - final_dict.panchayats = panchayatResponse; - - final_dict.region_name = blockName; + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(blockResponse) + .map(function(d) { + return d.value; + }) + // .sort(function(a, b) { + // var aTarget = a.data[a.data.length - 1]; + // var bTarget = b.data[b.data.length - 1]; + // var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + // var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + // return bSum - aSum; + // }); - return final_dict; + // Process list of panchayat names and codes + var panchayatResponse = D3.values(rows[3]); + // Nest the panchayat response + var panchayatPerformance = D3.nest() + .key(function(d) { + return d.block_code; + }) + .key(function(d) { + return d.panchayat_code; + }) + .rollup(function(v) { + return { + 'panchayat_code': v[0].panchayat_code, + 'panchayat_name': v[0].panchayat_name, + 'data': v.map(function(d) { + return [ + d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(panchayatResponse) + .map(function(d) { + return { + 'block_name': d.key, + 'data': d.values.map(function(e) { return e.values; }) + }; + }); + // .sort(function(a, b) { + // var aTarget = a.data[a.data.length - 1]; + // var bTarget = b.data[b.data.length - 1]; + // var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + // var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + // return bSum - aSum; + // }); + + + + + return data; } exports.district = function(rows) { diff --git a/app/helpers/queries.js b/app/helpers/queries.js index 3ad3f796..31da2d56 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -2,11 +2,10 @@ exports.performance = function(REGION_CODE, ROLE) { if (ROLE === 'block') { - return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code in (SELECT b.state_code FROM blocks b WHERE b.block_code ='" + REGION_CODE + "') GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + - "SELECT district_code,district_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM district_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.district_code in (SELECT b.district_code FROM blocks b WHERE b.block_code ='" + REGION_CODE + "') GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + - "SELECT block_code,block_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code ='" + REGION_CODE + "' GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + - "SELECT block_code,block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,0) mrc_mre,ROUND(mre_wlg_mean,0) mre_wlg,ROUND(wlg_wls_mean,0) wlg_wls,ROUND(wls_fto_mean,0) wls_fto,ROUND(fto_firstsign_mean,0) fto_sn1,ROUND(firstsign_secondsign_mean,0) sn1_sn2,ROUND(secondsign_processed_mean,0) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code ='" + REGION_CODE + "' ORDER BY date;" + - "SELECT panchayat_code,panchayat_name FROM panchayats WHERE block_code = REGION_CODE;"; + return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code IN (SELECT b.state_code FROM blocks b WHERE b.block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + + "SELECT district_code,district_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM district_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.district_code IN (SELECT b.district_code FROM blocks b WHERE b.block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + + "SELECT block_code, block_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;" + + "SELECT block_code, panchayat_code, panchayat_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), panchayat_code ORDER BY panchayat_code, date;"; } else if (ROLE === 'district') { return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code in (SELECT b.state_code FROM districts b WHERE b.district_code ='" + REGION_CODE + "') GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + From 3c866b472e815fe44c8af5a323a01b191d9c65d7 Mon Sep 17 00:00:00 2001 From: edodge Date: Thu, 4 Aug 2016 12:29:02 +0530 Subject: [PATCH 031/314] Working on performance parser --- app/controllers/musters/cards.js | 10 +++++--- app/helpers/performance_parser.js | 41 ++++++++++++++++--------------- app/helpers/queries.js | 2 +- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/app/controllers/musters/cards.js b/app/controllers/musters/cards.js index 3ce96880..7bac38c1 100644 --- a/app/controllers/musters/cards.js +++ b/app/controllers/musters/cards.js @@ -35,9 +35,8 @@ exports.getData = { // Nest the cards response var cards = D3.nest() .key(function(d) { - return d.block_name; + return d.block_code + d.block_name; }) - .sortKeys(D3.descending) .key(function(d) { return d.staff_id; }) @@ -77,8 +76,11 @@ exports.getData = { .entries(data) .map(function(d) { return { - 'block_name': d.key, - 'cards': d.values.map(function(e) { return e.values; }) + 'block_code': d.key.substr(0,7), + 'block_name': d.key.substr(7,), + 'cards': d.values.map(function(e) { + return e.values; + }) }; }); diff --git a/app/helpers/performance_parser.js b/app/helpers/performance_parser.js index 0c13e552..1dce8120 100644 --- a/app/helpers/performance_parser.js +++ b/app/helpers/performance_parser.js @@ -83,21 +83,22 @@ exports.block = function(rows) { .map(function(d) { return d.value; }) - // .sort(function(a, b) { - // var aTarget = a.data[a.data.length - 1]; - // var bTarget = b.data[b.data.length - 1]; - // var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - // var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - // return bSum - aSum; - // }); + .sort(function(a, b) { + var aTarget = a.data[a.data.length - 1]; + var bTarget = b.data[b.data.length - 1]; + var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; + var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; + return bSum - aSum; + }); // Process list of panchayat names and codes var panchayatResponse = D3.values(rows[3]); + // Nest the panchayat response var panchayatPerformance = D3.nest() .key(function(d) { - return d.block_code; + return d.block_code + d.block_name; }) .key(function(d) { return d.panchayat_code; @@ -108,7 +109,7 @@ exports.block = function(rows) { 'panchayat_name': v[0].panchayat_name, 'data': v.map(function(d) { return [ - d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), + d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), d.mrc_mre, d.mre_wlg, d.wlg_wls, @@ -124,20 +125,20 @@ exports.block = function(rows) { .entries(panchayatResponse) .map(function(d) { return { - 'block_name': d.key, - 'data': d.values.map(function(e) { return e.values; }) + 'block_code': d.key.substr(0,7), + 'block_name': d.key.substr(7,), + 'data': d.values.map(function(e) { + return e.values; + }) }; }); - // .sort(function(a, b) { - // var aTarget = a.data[a.data.length - 1]; - // var bTarget = b.data[b.data.length - 1]; - // var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - // var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - // return bSum - aSum; - // }); - - + var data = { + 'state_performance': statePerformance, + 'district_performance': districtPerformance, + 'block_performance': blockPerformance, + 'panchayat_performance': panchayatPerformance + } return data; } diff --git a/app/helpers/queries.js b/app/helpers/queries.js index 31da2d56..818398e4 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -5,7 +5,7 @@ exports.performance = function(REGION_CODE, ROLE) { return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code IN (SELECT b.state_code FROM blocks b WHERE b.block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + "SELECT district_code,district_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM district_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.district_code IN (SELECT b.district_code FROM blocks b WHERE b.block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + "SELECT block_code, block_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;" + - "SELECT block_code, panchayat_code, panchayat_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), panchayat_code ORDER BY panchayat_code, date;"; + "SELECT block_code, block_name, panchayat_code, panchayat_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), panchayat_code ORDER BY panchayat_code, date;"; } else if (ROLE === 'district') { return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code in (SELECT b.state_code FROM districts b WHERE b.district_code ='" + REGION_CODE + "') GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + From 01d59a0ebb77a2df7503738a5d36da9d003959a6 Mon Sep 17 00:00:00 2001 From: edodge Date: Thu, 4 Aug 2016 12:37:47 +0530 Subject: [PATCH 032/314] Complete block performance parser --- app/helpers/performance_parser.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/helpers/performance_parser.js b/app/helpers/performance_parser.js index 1dce8120..00c53900 100644 --- a/app/helpers/performance_parser.js +++ b/app/helpers/performance_parser.js @@ -82,13 +82,6 @@ exports.block = function(rows) { .entries(blockResponse) .map(function(d) { return d.value; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; }); From 79537ee49f00d21e8ffb3044a29797695a8d29d3 Mon Sep 17 00:00:00 2001 From: edodge Date: Thu, 4 Aug 2016 13:02:59 +0530 Subject: [PATCH 033/314] Complete district performance queries and parser --- app/helpers/queries.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/helpers/queries.js b/app/helpers/queries.js index 818398e4..219733d4 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -8,9 +8,10 @@ exports.performance = function(REGION_CODE, ROLE) { "SELECT block_code, block_name, panchayat_code, panchayat_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), panchayat_code ORDER BY panchayat_code, date;"; } else if (ROLE === 'district') { - return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code in (SELECT b.state_code FROM districts b WHERE b.district_code ='" + REGION_CODE + "') GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + - "SELECT district_code,district_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM district_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.district_code='" + REGION_CODE + "' GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + - "SELECT district_code,district_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,0) mrc_mre,ROUND(mre_wlg_mean,0) mre_wlg,ROUND(wlg_wls_mean,0) wlg_wls,ROUND(wls_fto_mean,0) wls_fto,ROUND(fto_firstsign_mean,0) fto_sn1,ROUND(firstsign_secondsign_mean,0) sn1_sn2,ROUND(secondsign_processed_mean,0) sn2_prc FROM district_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code ='" + REGION_CODE + "' ORDER BY date;"; + return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code IN (SELECT b.state_code FROM districts b WHERE b.district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + + "SELECT district_code, district_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM district_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), district_code ORDER BY district_code, date;" + + "SELECT district_code, district_name, block_code, block_name, SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;"; + } }; From e21ac8877b1196bdee7dbb0b500ff696f197fa7e Mon Sep 17 00:00:00 2001 From: edodge Date: Thu, 4 Aug 2016 13:06:52 +0530 Subject: [PATCH 034/314] Complete district performance queries and parser --- app/helpers/performance_parser.js | 126 +++++++++++++++++++----------- 1 file changed, 80 insertions(+), 46 deletions(-) diff --git a/app/helpers/performance_parser.js b/app/helpers/performance_parser.js index 00c53900..09f5fc1e 100644 --- a/app/helpers/performance_parser.js +++ b/app/helpers/performance_parser.js @@ -138,13 +138,12 @@ exports.block = function(rows) { exports.district = function(rows) { - - // process state data - var stateResponse = Utils.flatten(rows[0]); + // Process state data + var stateResponse = D3.values(rows[0]); var stateName = stateResponse[0].state_name; var stateCode = stateResponse[0].state_code; - final_dict.monthwise.state = { + var statePerformance = { 'state_code': stateCode, 'state_name': stateName, 'data': stateResponse.map(function(d) { @@ -162,50 +161,85 @@ exports.district = function(rows) { }) }; - // Process district data for bottom chart (monthwise data) - var districtResponse = Utils.flatten(rows[1]); - var districtName = districtResponse[0].district_name; - var districtCode = districtResponse[0].district_code; - final_dict.monthwise.district = { - 'district_code': districtCode, - 'district_name': districtName, - 'data': districtResponse.map(function(d) { - return [ - d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; + // Process district data for bottom chart (grouped by month) + var districtResponse = D3.values(rows[1]); + + // Nest the block response (may be multiple blocks) + var districtPerformance = D3.nest() + .key(function(d) { + return d.district_code; }) - }; + .rollup(function(v) { + return { + 'district_code': v[0].district_code, + 'district_name': v[0].district_name, + 'data': v.map(function(d) { + return [ + d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(districtResponse) + .map(function(d) { + return d.value; + }); - // Process district data for top chart (datewise data) - var districtResponse = Utils.flatten(rows[2]); - var districtName = districtResponse[0].district_name; - var districtCode = districtResponse[0].district_code; - final_dict.datewise.district = { - 'district_code': districtCode, - 'district_name': districtName, - 'data': districtResponse.map(function(d) { - return [ - d.date.getFullYear() + '' + Utils.padNum(d.date.getMonth() + 1) + '' + Utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; + + // Process list of block names and codes + var blockResponse = D3.values(rows[2]); + + // Nest the block response + var blockPerformance = D3.nest() + .key(function(d) { + return d.district_code + d.district_name; }) - }; + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'data': v.map(function(d) { + return [ + d.year + '' + Utils.padNum(d.month) + '' + Utils.padNum(1), + d.mrc_mre, + d.mre_wlg, + d.wlg_wls, + d.wls_fto, + d.fto_sn1, + d.sn1_sn2, + d.sn2_prc, + d.tot_trn + ]; + }) + }; + }) + .entries(blockResponse) + .map(function(d) { + return { + 'district_code': d.key.substr(0,4), + 'district_name': d.key.substr(4,), + 'data': d.values.map(function(e) { + return e.values; + }) + }; + }); - final_dict.region_name = districtName; - return final_dict; + var data = { + 'state_performance': statePerformance, + 'district_performance': districtPerformance, + 'block_performance': blockPerformance + } + + return data; } From 459883313c8413f90eea9166741915a5c54d1a88 Mon Sep 17 00:00:00 2001 From: edodge Date: Thu, 4 Aug 2016 13:15:28 +0530 Subject: [PATCH 035/314] Clean up queries file --- app/controllers/musters/cards.js | 68 ++----------------- app/controllers/performance/performance.js | 9 +-- app/helpers/cards_parser.js | 77 ++++++++++++++++++++++ app/helpers/queries.js | 53 ++++++--------- 4 files changed, 106 insertions(+), 101 deletions(-) create mode 100644 app/helpers/cards_parser.js diff --git a/app/controllers/musters/cards.js b/app/controllers/musters/cards.js index 7bac38c1..ecfd895d 100644 --- a/app/controllers/musters/cards.js +++ b/app/controllers/musters/cards.js @@ -26,72 +26,12 @@ exports.getData = { if (role === 'block') { - var cardsResponse = D3.values(rows[0]); + var data = CardsParser(rows); - var stateResponse = D3.values(rows[1]); + } else if (role === 'district') { + + - var state_code = stateResponse[0].state_code; - - // Nest the cards response - var cards = D3.nest() - .key(function(d) { - return d.block_code + d.block_name; - }) - .key(function(d) { - return d.staff_id; - }) - .rollup(function(v) { - return { - 'name': v[0].name, - 'staff_id': v[0].staff_id, - 'designation': v[0].task_assign, - 'mobile': v[0].mobile_no, - 'current_total': v[0].current_total, - 'delayed_total': v[0].delayed_total, - 'delayed_musters': v.filter(function(d) { - return d.type === 'delayed_musters'; - }).map(function(d) { - return { - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date, - 'days_pending': d.days_pending - }; - }), - 'current_musters': v.filter(function(d) { - return d.type === 'current_musters'; - }).map(function(d) { - return { - 'msr_no': d.msr_no, - 'panchayat_name': d.panchayat_name, - 'work_name': d.work_name, - 'work_code': d.work_code, - 'closure_date': d.end_date - }; - }) - }; - }) - .entries(data) - .map(function(d) { - return { - 'block_code': d.key.substr(0,7), - 'block_name': d.key.substr(7,), - 'cards': d.values.map(function(e) { - return e.values; - }) - }; - }); - - var data = { - 'cards': cards - }; - - } - - if (role === 'district') { - // } diff --git a/app/controllers/performance/performance.js b/app/controllers/performance/performance.js index 9c0be4eb..b21e59ab 100644 --- a/app/controllers/performance/performance.js +++ b/app/controllers/performance/performance.js @@ -22,13 +22,14 @@ exports.getData = { type: sequelize.QueryTypes.SELECT }).then(function(rows) { - if (role === 'block') { + var data = PerformanceParser.block(rows); - } - if (role === 'district') { + } else if (role === 'district') { + var data = PerformanceParser.district(rows); + } data.config = { @@ -40,7 +41,7 @@ exports.getData = { comparison_lines: role === 'block' ? ['block', 'district', 'state'] : ['district', 'state'] }; - reply(final_dict); + reply(data); }); } }; diff --git a/app/helpers/cards_parser.js b/app/helpers/cards_parser.js new file mode 100644 index 00000000..a2b0558d --- /dev/null +++ b/app/helpers/cards_parser.js @@ -0,0 +1,77 @@ +'use strict'; + +var Utils = require('./utils'); +const D3 = require('D3'); + +exports.block = function(rows) { + + var cardsResponse = D3.values(rows[0]); + + var stateResponse = D3.values(rows[1]); + + var stateCode = stateResponse[0].state_code; + + // Nest the cards response + var cards = D3.nest() + .key(function(d) { + return d.block_code + d.block_name; + }) + .key(function(d) { + return d.staff_id; + }) + .rollup(function(v) { + return { + 'name': v[0].name, + 'staff_id': v[0].staff_id, + 'designation': Utils.getDesignation(v[0].task_assign, stateCode), + 'mobile': v[0].mobile_no, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'delayed_musters': v.filter(function(d) { + return d.type === 'delayed_musters'; + }).map(function(d) { + return { + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date, + 'days_pending': d.days_pending + }; + }), + 'current_musters': v.filter(function(d) { + return d.type === 'current_musters'; + }).map(function(d) { + return { + 'msr_no': d.msr_no, + 'panchayat_name': d.panchayat_name, + 'work_name': d.work_name, + 'work_code': d.work_code, + 'closure_date': d.end_date + }; + }) + }; + }) + .entries(data) + .map(function(d) { + return { + 'block_code': d.key.substr(0,7), + 'block_name': d.key.substr(7,), + 'cards': d.values.map(function(e) { + return e.values; + }) + }; + }); + + var data = { + 'cards': cards + }; + + return data; +} + +exports.district = function(rows) { + + + return data; +} diff --git a/app/helpers/queries.js b/app/helpers/queries.js index 219733d4..fe3574a0 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -1,19 +1,11 @@ 'use strict'; -exports.performance = function(REGION_CODE, ROLE) { +exports.overview = function(USER_ID, ROLE) { if (ROLE === 'block') { - return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code IN (SELECT b.state_code FROM blocks b WHERE b.block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + - "SELECT district_code,district_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM district_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.district_code IN (SELECT b.district_code FROM blocks b WHERE b.block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + - "SELECT block_code, block_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;" + - "SELECT block_code, block_name, panchayat_code, panchayat_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), panchayat_code ORDER BY panchayat_code, date;"; - + return "SELECT a.region_code, a.region_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, IFNULL(d.days_to_payment,'No Data') AS days_to_payment FROM (SELECT region_code, region_name FROM user_regions WHERE user_id='"+USER_ID+"') a LEFT JOIN (SELECT count(*) AS current_total, block_code AS region_code FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY region_code) b ON a.region_code = b.region_code LEFT JOIN (SELECT count(*) AS delayed_total, block_code AS region_code FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY region_code) c ON a.region_code = c.region_code LEFT JOIN (SELECT ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1) AS days_to_payment, block_code AS region_code FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY region_code) d ON a.region_code = d.region_code;"; } else if (ROLE === 'district') { - return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code IN (SELECT b.state_code FROM districts b WHERE b.district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + - "SELECT district_code, district_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM district_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), district_code ORDER BY district_code, date;" + - "SELECT district_code, district_name, block_code, block_name, SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;"; - + return "SELECT a.region_code, a.region_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, IFNULL(d.days_to_payment,'No Data') AS days_to_payment FROM (SELECT region_code, region_name FROM user_regions WHERE user_id='"+USER_ID+"') a LEFT JOIN (SELECT count(*) AS current_total, b.district_code AS region_code FROM current_musters a RIGHT JOIN (SELECT district_code, block_code from blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code GROUP BY region_code ) b ON a.region_code = b.region_code LEFT JOIN (SELECT count(*) AS delayed_total, b.district_code AS region_code FROM delayed_musters a RIGHT JOIN (SELECT district_code, block_code from blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code GROUP BY region_code ) c ON a.region_code = c.region_code LEFT JOIN (SELECT ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1) AS days_to_payment, district_code AS region_code FROM district_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY region_code) d ON a.region_code = d.region_code;"; } - }; exports.cards = function(USER_ID, ROLE) { @@ -21,32 +13,19 @@ exports.cards = function(USER_ID, ROLE) { return "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + "SELECT DISTINCT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"');"; } -} +}; -exports.overview = function(USER_ID, ROLE) { +exports.performance = function(REGION_CODE, ROLE) { if (ROLE === 'block') { - return "SELECT a.region_code, a.region_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, IFNULL(d.days_to_payment,'No Data') AS days_to_payment FROM (SELECT region_code, region_name FROM user_regions WHERE user_id='"+USER_ID+"') a LEFT JOIN (SELECT count(*) AS current_total, block_code AS region_code FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY region_code) b ON a.region_code = b.region_code LEFT JOIN (SELECT count(*) AS delayed_total, block_code AS region_code FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY region_code) c ON a.region_code = c.region_code LEFT JOIN (SELECT ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1) AS days_to_payment, block_code AS region_code FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY region_code) d ON a.region_code = d.region_code;"; + return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code IN (SELECT b.state_code FROM blocks b WHERE b.block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + + "SELECT district_code,district_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM district_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.district_code IN (SELECT b.district_code FROM blocks b WHERE b.block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + + "SELECT block_code, block_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;" + + "SELECT block_code, block_name, panchayat_code, panchayat_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), panchayat_code ORDER BY panchayat_code, date;"; } else if (ROLE === 'district') { - return "SELECT a.region_code, a.region_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, IFNULL(d.days_to_payment,'No Data') AS days_to_payment FROM (SELECT region_code, region_name FROM user_regions WHERE user_id='"+USER_ID+"') a LEFT JOIN (SELECT count(*) AS current_total, b.district_code AS region_code FROM current_musters a RIGHT JOIN (SELECT district_code, block_code from blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code GROUP BY region_code ) b ON a.region_code = b.region_code LEFT JOIN (SELECT count(*) AS delayed_total, b.district_code AS region_code FROM delayed_musters a RIGHT JOIN (SELECT district_code, block_code from blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code GROUP BY region_code ) c ON a.region_code = c.region_code LEFT JOIN (SELECT ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1) AS days_to_payment, district_code AS region_code FROM district_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY region_code) d ON a.region_code = d.region_code;"; + return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code IN (SELECT b.state_code FROM districts b WHERE b.district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + + "SELECT district_code, district_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM district_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), district_code ORDER BY district_code, date;" + + "SELECT district_code, district_name, block_code, block_name, SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;"; } - -} - -exports.panchayatPerformance = function(REGION_CODE) { - return "SELECT panchayat_name as region_name from panchayats where panchayat_code=" + REGION_CODE + ";" + - "SELECT panchayat_code AS region_code,panchayat_name AS region_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,0) mrc_mre,ROUND(mre_wlg_mean,0) mre_wlg,ROUND(wlg_wls_mean,0) wlg_wls,ROUND(wls_fto_mean,0) wls_fto,ROUND(fto_firstsign_mean,0) fto_sn1,ROUND(firstsign_secondsign_mean,0) sn1_sn2,ROUND(secondsign_processed_mean,0) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND panchayat_code ='" + REGION_CODE + "' ORDER BY panchayat_code, date;"; -}; - -exports.userBlocks = function(USER_ID) { - return "SELECT block_code FROM user_blocks WHERE id = " + USER_ID + ");"; -}; - -exports.outcomes = function() { - return "SELECT outcome, label FROM outcomes;" + - "SELECT date, mean, upper, outcome, lower, treatment FROM estimates_series;" + - "SELECT * FROM estimates_summary;" + - "SELECT date, mean, upper, outcome, lower, arm FROM estimates_series_arms;" + // arm === (1,2,3) - "SELECT t1_mean, t2_mean, t3_mean, p_val, outcome FROM estimates_summary_arms;"; }; exports.paydroid = function(USER_ID,ROLE,VERSION) { @@ -77,3 +56,11 @@ exports.paydroid = function(USER_ID,ROLE,VERSION) { } } }; + +exports.outcomes = function() { + return "SELECT outcome, label FROM outcomes;" + + "SELECT date, mean, upper, outcome, lower, treatment FROM estimates_series;" + + "SELECT * FROM estimates_summary;" + + "SELECT date, mean, upper, outcome, lower, arm FROM estimates_series_arms;" + // arm === (1,2,3) + "SELECT t1_mean, t2_mean, t3_mean, p_val, outcome FROM estimates_summary_arms;"; +}; From f5792baa16c5ec4e02357e67f161d4cbde201a3e Mon Sep 17 00:00:00 2001 From: edodge Date: Thu, 4 Aug 2016 13:40:00 +0530 Subject: [PATCH 036/314] Add district version to cards parser and queries --- app/controllers/musters/cards.js | 8 +- app/controllers/performance/discrete.js | 38 ----- app/controllers/performance/panchayat.js | 54 ------ app/helpers/cards_parser.js | 51 +++++- app/helpers/discrete_parser.js | 199 ----------------------- app/helpers/performance_parser.js | 2 +- app/helpers/queries.js | 2 + 7 files changed, 56 insertions(+), 298 deletions(-) delete mode 100644 app/controllers/performance/discrete.js delete mode 100644 app/controllers/performance/panchayat.js delete mode 100644 app/helpers/discrete_parser.js diff --git a/app/controllers/musters/cards.js b/app/controllers/musters/cards.js index ecfd895d..65f0209b 100644 --- a/app/controllers/musters/cards.js +++ b/app/controllers/musters/cards.js @@ -3,8 +3,6 @@ const Queries = require('../../helpers/queries'); const CardsParser = require('../../helpers/cards_parser'); const Translate = require('../../templates/helpers/t'); -const Utils = require('../../helpers/utils'); -const D3 = require('d3'); exports.showPage = { handler: function(request, reply) { @@ -26,16 +24,16 @@ exports.getData = { if (role === 'block') { - var data = CardsParser(rows); + var data = CardsParser.block(rows); } else if (role === 'district') { - + var data = CardsParser.district(rows); } - reply(data); + }); } }; diff --git a/app/controllers/performance/discrete.js b/app/controllers/performance/discrete.js deleted file mode 100644 index ba4be02d..00000000 --- a/app/controllers/performance/discrete.js +++ /dev/null @@ -1,38 +0,0 @@ -'use strict'; - -var Queries = require('../../helpers/queries'); -var DiscreteParser = require('../../helpers/discrete_parser'); - -exports.showPage = { - auth: { - strategy: 'standard' - }, - handler: function(request, reply) { - return reply.view('performance/discrete'); - } -}; - - -exports.getData = { - handler: function(request, reply) { - - var sequelize = request.server.plugins.sequelize.db.sequelize; - var region_code = request.query.region_code; - var role = request.auth.credentials.role; - var queryString = Queries.discretePerformance(region_code, role); - - sequelize.query(queryString, { - type: sequelize.QueryTypes.SELECT - }).then(function(rows) { - - if (role === 'block') { - var final_dict = DiscreteParser.block(rows, role, request.auth.credentials); - } else if (role === 'district') { - var final_dict = DiscreteParser.district(rows, role, request.auth.credentials); - } - - reply(final_dict); - }); - - } -}; diff --git a/app/controllers/performance/panchayat.js b/app/controllers/performance/panchayat.js deleted file mode 100644 index 062e0b4d..00000000 --- a/app/controllers/performance/panchayat.js +++ /dev/null @@ -1,54 +0,0 @@ -'use strict'; - -var Queries = require('../../helpers/queries'); -var Utils = require('../../helpers/utils'); -var Translate = require('../../templates/helpers/t'); - -exports.getData = { - handler: function(request, reply) { - - var sequelize = request.server.plugins.sequelize.db.sequelize; - var region_code = request.query.panchayat_code; - var queryString = Queries.panchayatPerformance(region_code); - - sequelize.query(queryString, { - type: sequelize.QueryTypes.SELECT - }).then(function(rows) { - - var final_dict = {}; - var regionResponse = Utils.flatten(rows[0]); - var panchayatResponse = Utils.flatten(rows[1]); - var panchayatName = regionResponse[0].region_name; - var panchayatCode = region_code; - final_dict.panchayat = { - 'panchayat_code': panchayatCode, - 'panchayat_name': panchayatName, - 'data': panchayatResponse.map(function(d) { - return [ - d.date.getFullYear() + '' + Utils.padNum(d.date.getMonth() + 1) + '' + Utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - - final_dict.config = { - 'headers': ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn'], - labels: Translate('/payment_steps_labels', request.auth.credentials), - y_axis_label: Translate('/y_axis_labels', request.auth.credentials), - sidebar: { - avg_days: Translate('/performance/discrete/sidebar/avg_days', credentials), - total_trans: Translate('/performance/discrete/sidebar/total_trans', credentials), - } - }; - reply(final_dict); - }); - - } -}; diff --git a/app/helpers/cards_parser.js b/app/helpers/cards_parser.js index a2b0558d..65e7f4bf 100644 --- a/app/helpers/cards_parser.js +++ b/app/helpers/cards_parser.js @@ -1,6 +1,6 @@ 'use strict'; -var Utils = require('./utils'); +const Utils = require('./utils'); const D3 = require('D3'); exports.block = function(rows) { @@ -72,6 +72,55 @@ exports.block = function(rows) { exports.district = function(rows) { + var cardsResponse = D3.values(rows[0]); + + // Nest the cards response + var cards = D3.nest() + .key(function(d) { + return d.district_code + d.district_name + }) + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'officers': v.map(function(d) { + return { + name: d.id == null ? 'No Data' : d.firstname + ' ' + d.lastname, + designation: d.designation, + mobile: d.mobile + }; + }), + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 't2_total': v[0].t2_total, + 't2_avg': v[0].t2_avg, + 't5_total': v[0].t5_total, + 't5_avg': v[0].t5_avg, + 't6_total': v[0].t6_total, + 't6_avg': v[0].t6_avg, + 't7_total': v[0].t7_total, + 't7_avg': v[0].t7_avg, + 't8_total': v[0].t8_total, + 't8_avg': v[0].t8_avg + }; + }) + .entries(cardsResponse) + .map(function(d) { + return { + 'district_code': d.key.substr(0,4), + 'district_name': d.key.substr(4,), + 'data': d.values.map(function(e) { + return e.values; + }) + }; + }); + var data = { + 'cards': cards + }; + return data; } diff --git a/app/helpers/discrete_parser.js b/app/helpers/discrete_parser.js deleted file mode 100644 index 64ce3c48..00000000 --- a/app/helpers/discrete_parser.js +++ /dev/null @@ -1,199 +0,0 @@ -'use strict'; - -var Utils = require('./utils'); -var D3 = require('d3'); -var Translate = require('../templates/helpers/t'); - -exports.block = function(rows, role, credentials) { - var final_dict = {}; - var regionName = rows[0][0].region_name; - - final_dict.region_name = regionName; - - var childrenResponse = Utils.flatten(rows[1]); - - var employeeResponse = Utils.flatten(rows[2]); - - var empMapping = { - 'TA': Utils.nestEmpMapping(rows[3]), - 'GRS': Utils.nestEmpMapping(rows[4]) - }; - - var employeeStats = { - 'past30': { - 'TA': Utils.nestEmpStats(rows[5]), - 'GRS': Utils.nestEmpStats(rows[6]) - }, - 'past60': { - 'TA': Utils.nestEmpStats(rows[7]), - 'GRS': Utils.nestEmpStats(rows[8]) - }, - 'all': { - 'TA': Utils.nestEmpStats(rows[9]), - 'GRS': Utils.nestEmpStats(rows[10]) - } - }; - - var mappingResponse = Utils.flatten(rows[11]); - - // process children data - final_dict.discrete = D3.nest() - .key(function(d) { - return d.region_code; - }) - .rollup(function(v) { - return { - 'region_code': v[0].region_code, - 'region_name': v[0].region_name, - 'mapped_ta': empMapping.TA[v[0].region_code], - 'mapped_grs': empMapping.GRS[v[0].region_code], - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + Utils.padNum(d.date.getMonth() + 1) + '' + Utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }) - }; - }) - .entries(childrenResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - // process employee data - final_dict.employees = D3.nest() - .key(function(d) { - return d.task_assign; - }) - .rollup(function(v) { - return D3.nest() - .key(function(d) { - return d.staff_id; - }) - .rollup(function(w) { - return { - 'staff_id': w[0].staff_id, - 'name': w[0].name, - 'mobile': w[0].mobile_no, - 'step1_avg_30': employeeStats.past30[w[0].task_assign][w[0].staff_id].step1_avg, - 'tot_trans_30': employeeStats.past30[w[0].task_assign][w[0].staff_id].total_transactions || 0, - 'step1_avg_60': employeeStats.past60[w[0].task_assign][w[0].staff_id].step1_avg, - 'tot_trans_60': employeeStats.past60[w[0].task_assign][w[0].staff_id].total_transactions || 0, - 'step1_avg_all': employeeStats.all[w[0].task_assign][w[0].staff_id].step1_avg, - 'tot_trans_all': employeeStats.all[w[0].task_assign][w[0].staff_id].total_transactions || 0, - 'panchayats': w.map(function(d) { - return { - 'region_code': d.map_location, - 'region_name': d.mapped_panchayat_name - }; - }) - }; - }) - .entries(v) - .map(function(d) { - return d.values; - }); - - }) - .map(employeeResponse); - - final_dict.mapping = { - 'total_panchayat_count': mappingResponse[0].total_panchayat_count, - 'grs_panchayat_count': mappingResponse[0].grs_panchayat_count, - 'ta_panchayat_count': mappingResponse[0].ta_panchayat_count - }; - - final_dict.config = { - 'headers': ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn'], - 'role': role, - 'labels': Translate('/payment_steps_labels', credentials), - 'y_axis_labels': Translate('/y_axis_labels', credentials), - 'sidebar': { - avg_days: Translate('/performance/discrete/sidebar/avg_days', credentials), - total_trans: Translate('/performance/discrete/sidebar/total_trans', credentials), - } - }; - - return final_dict; -} - -exports.district = function(rows, role, credentials) { - - var final_dict = {}; - var regionName = rows[0][0].region_name; - - final_dict.region_name = regionName; - - var blockResponse = Utils.flatten(rows[1]); - var panchayatResponse = Utils.flatten(rows[2]); - - // process children data - final_dict.discrete = D3.nest() - .key(function(d) { - return d.region_code; - }) - .rollup(function(v) { - return { - 'block_code': v[0].region_code, - 'block_name': v[0].region_name, - 'data': v.map(function(d) { - return [ - d.date.getFullYear() + '' + Utils.padNum(d.date.getMonth() + 1) + '' + Utils.padNum(d.date.getDate()), - d.mrc_mre, - d.mre_wlg, - d.wlg_wls, - d.wls_fto, - d.fto_sn1, - d.sn1_sn2, - d.sn2_prc, - d.tot_trn - ]; - }), - 'panchayats': panchayatResponse.filter(function(d) { - return d.block_code === v[0].region_code; - }).map(function(d) { - return { - 'panchayat_code': d.panchayat_code, - 'panchayat_name': d.panchayat_name - }; - }) - }; - }) - .entries(blockResponse) - .map(function(d) { - return d.values; - }) - .sort(function(a, b) { - var aTarget = a.data[a.data.length - 1]; - var bTarget = b.data[b.data.length - 1]; - var aSum = aTarget[1] + aTarget[2] + aTarget[3] + aTarget[4] + aTarget[5] + aTarget[6] + aTarget[7]; - var bSum = bTarget[1] + bTarget[2] + bTarget[3] + bTarget[4] + bTarget[5] + bTarget[6] + bTarget[7]; - return bSum - aSum; - }); - - final_dict.config = { - 'headers': ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn'], - 'role': role, - 'labels': Translate('/payment_steps_labels', credentials), - 'y_axis_label': Translate('/y_axis_labels', credentials), - 'sidebar': { - avg_days: Translate('/performance/discrete/sidebar/avg_days', credentials), - total_trans: Translate('/performance/discrete/sidebar/total_trans', credentials), - } - }; - return final_dict; -} diff --git a/app/helpers/performance_parser.js b/app/helpers/performance_parser.js index 09f5fc1e..f07426c3 100644 --- a/app/helpers/performance_parser.js +++ b/app/helpers/performance_parser.js @@ -1,6 +1,6 @@ 'use strict'; -var Utils = require('./utils'); +const Utils = require('./utils'); const D3 = require('D3'); exports.block = function(rows) { diff --git a/app/helpers/queries.js b/app/helpers/queries.js index fe3574a0..ddcb1860 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -12,6 +12,8 @@ exports.cards = function(USER_ID, ROLE) { if (ROLE === 'block') { return "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + "SELECT DISTINCT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"');"; + } else if (ROLE === 'district') { + return "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, b.days_to_payment, c.current_total, d.delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;"; } }; From 6ed2b5b0e5fe65cc05e3f67f7795af76beefbab0 Mon Sep 17 00:00:00 2001 From: edodge Date: Thu, 4 Aug 2016 13:43:07 +0530 Subject: [PATCH 037/314] Update 'cards' naming to 'musters' --- app/controllers/musters/{cards.js => musters.js} | 8 ++++---- app/helpers/{cards_parser.js => musters_parser.js} | 0 2 files changed, 4 insertions(+), 4 deletions(-) rename app/controllers/musters/{cards.js => musters.js} (77%) rename app/helpers/{cards_parser.js => musters_parser.js} (100%) diff --git a/app/controllers/musters/cards.js b/app/controllers/musters/musters.js similarity index 77% rename from app/controllers/musters/cards.js rename to app/controllers/musters/musters.js index 65f0209b..d2921a31 100644 --- a/app/controllers/musters/cards.js +++ b/app/controllers/musters/musters.js @@ -1,12 +1,12 @@ 'use strict'; const Queries = require('../../helpers/queries'); -const CardsParser = require('../../helpers/cards_parser'); +const MustersParser = require('../../helpers/musters_parser'); const Translate = require('../../templates/helpers/t'); exports.showPage = { handler: function(request, reply) { - return reply.view('musters/cards'); + return reply.view('musters/musters'); } }; @@ -24,11 +24,11 @@ exports.getData = { if (role === 'block') { - var data = CardsParser.block(rows); + var data = MustersParser.block(rows); } else if (role === 'district') { - var data = CardsParser.district(rows); + var data = MustersParser.district(rows); } diff --git a/app/helpers/cards_parser.js b/app/helpers/musters_parser.js similarity index 100% rename from app/helpers/cards_parser.js rename to app/helpers/musters_parser.js From 65b87237fc5731a0bd035082b27a397528709070 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 4 Aug 2016 14:10:08 +0530 Subject: [PATCH 038/314] Fix assets pipeline --- config/assets.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/assets.js b/config/assets.js index dd13e20c..512d1d4c 100644 --- a/config/assets.js +++ b/config/assets.js @@ -30,7 +30,7 @@ internals.paths = { ] }; -internals.store = new Confidence.Store(internals.config); +internals.store = new Confidence.Store(internals.paths); exports.get = function(key) { return internals.store.get(key, internals.criteria); From 141bb81b51b6961def63e917ef27221dbf081dfd Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 4 Aug 2016 17:46:20 +0530 Subject: [PATCH 039/314] Update route configuration --- app/routes/musters.js | 12 +++++------- app/routes/overview.js | 29 +++++++++++++++++++++++++++++ app/routes/performance.js | 30 ++++++------------------------ 3 files changed, 40 insertions(+), 31 deletions(-) create mode 100644 app/routes/overview.js diff --git a/app/routes/musters.js b/app/routes/musters.js index d467bcc7..257f83a1 100644 --- a/app/routes/musters.js +++ b/app/routes/musters.js @@ -3,9 +3,7 @@ exports.register = function(plugin, options, next) { const Controllers = { - musters: { - cards: require('../controllers/musters/cards') - } + musters: require('../controllers/musters/musters') }; plugin.route([ @@ -13,15 +11,15 @@ exports.register = function(plugin, options, next) { // Muster cards { method: 'GET', - path: '/musters/cards', - config: Controllers.musters.cards.showPage + path: '/musters', + config: Controllers.musters.showPage }, // Muster cards data { method: 'GET', - path: '/musters/cards/data', - config: Controllers.musters.cards.getData + path: '/musters/data', + config: Controllers.musters.getData }, ]); diff --git a/app/routes/overview.js b/app/routes/overview.js new file mode 100644 index 00000000..64451356 --- /dev/null +++ b/app/routes/overview.js @@ -0,0 +1,29 @@ +'use strict'; + +exports.register = function(plugin, options, next) { + + const Controllers = { + overview: require('../controllers/overview/overview') + }; + + plugin.route([ + + // Performance + { + method: 'GET', + path: '/overview', + config: Controllers.overview.showPage + }, { + method: 'GET', + path: '/overview/data', + config: Controllers.overview.getData + } + ]); + + next(); +}; + +exports.register.attributes = { + name: 'overview_routes', + version: require('../../package.json').version +}; diff --git a/app/routes/performance.js b/app/routes/performance.js index 13fe4f45..42e33253 100644 --- a/app/routes/performance.js +++ b/app/routes/performance.js @@ -3,38 +3,20 @@ exports.register = function(plugin, options, next) { const Controllers = { - performance: { - overview: require('../controllers/performance/overview'), - discrete: require('../controllers/performance/discrete'), - panchayat: require('../controllers/performance/panchayat') - } + performance: require('../controllers/performance/performance') }; plugin.route([ - // Overview Performance + // Performance { method: 'GET', - path: '/performance/overview', - config: Controllers.performance.overview.showPage - }, { - method: 'GET', - path: '/performance/overview/data', - config: Controllers.performance.overview.getData - }, - // Discrete Performance - { - method: 'GET', - path: '/performance/discrete', - config: Controllers.performance.discrete.showPage - }, { - method: 'GET', - path: '/performance/discrete/data', - config: Controllers.performance.discrete.getData + path: '/performance', + config: Controllers.performance.showPage }, { method: 'GET', - path: '/performance/panchayat/data', - config: Controllers.performance.panchayat.getData + path: '/performance/data', + config: Controllers.performance.getData } ]); From eb8bcc4805227e780eaf410b5bda91c6d00dc08d Mon Sep 17 00:00:00 2001 From: edodge Date: Thu, 4 Aug 2016 17:49:06 +0530 Subject: [PATCH 040/314] Fix error in substr method --- app/helpers/musters_parser.js | 4 ++-- app/helpers/performance_parser.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/helpers/musters_parser.js b/app/helpers/musters_parser.js index 65e7f4bf..cac79420 100644 --- a/app/helpers/musters_parser.js +++ b/app/helpers/musters_parser.js @@ -56,7 +56,7 @@ exports.block = function(rows) { .map(function(d) { return { 'block_code': d.key.substr(0,7), - 'block_name': d.key.substr(7,), + 'block_name': d.key.substr(7), 'cards': d.values.map(function(e) { return e.values; }) @@ -111,7 +111,7 @@ exports.district = function(rows) { .map(function(d) { return { 'district_code': d.key.substr(0,4), - 'district_name': d.key.substr(4,), + 'district_name': d.key.substr(4), 'data': d.values.map(function(e) { return e.values; }) diff --git a/app/helpers/performance_parser.js b/app/helpers/performance_parser.js index f07426c3..14d70568 100644 --- a/app/helpers/performance_parser.js +++ b/app/helpers/performance_parser.js @@ -119,7 +119,7 @@ exports.block = function(rows) { .map(function(d) { return { 'block_code': d.key.substr(0,7), - 'block_name': d.key.substr(7,), + 'block_name': d.key.substr(7), 'data': d.values.map(function(e) { return e.values; }) @@ -228,7 +228,7 @@ exports.district = function(rows) { .map(function(d) { return { 'district_code': d.key.substr(0,4), - 'district_name': d.key.substr(4,), + 'district_name': d.key.substr(4), 'data': d.values.map(function(e) { return e.values; }) From 602aaa2f8a573b4dd7ece3e69e5047bd8cd57743 Mon Sep 17 00:00:00 2001 From: edodge Date: Thu, 4 Aug 2016 19:23:40 +0530 Subject: [PATCH 041/314] Debug musters data --- app/controllers/musters/musters.js | 2 +- app/helpers/musters_parser.js | 9 ++++----- app/helpers/queries.js | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/app/controllers/musters/musters.js b/app/controllers/musters/musters.js index d2921a31..e35a8af5 100644 --- a/app/controllers/musters/musters.js +++ b/app/controllers/musters/musters.js @@ -27,7 +27,7 @@ exports.getData = { var data = MustersParser.block(rows); } else if (role === 'district') { - + var data = MustersParser.district(rows); } diff --git a/app/helpers/musters_parser.js b/app/helpers/musters_parser.js index cac79420..da25f6c8 100644 --- a/app/helpers/musters_parser.js +++ b/app/helpers/musters_parser.js @@ -22,7 +22,6 @@ exports.block = function(rows) { .rollup(function(v) { return { 'name': v[0].name, - 'staff_id': v[0].staff_id, 'designation': Utils.getDesignation(v[0].task_assign, stateCode), 'mobile': v[0].mobile_no, 'current_total': v[0].current_total, @@ -52,13 +51,13 @@ exports.block = function(rows) { }) }; }) - .entries(data) + .entries(cardsResponse) .map(function(d) { return { 'block_code': d.key.substr(0,7), 'block_name': d.key.substr(7), 'cards': d.values.map(function(e) { - return e.values; + return e.value; }) }; }); @@ -72,7 +71,7 @@ exports.block = function(rows) { exports.district = function(rows) { - var cardsResponse = D3.values(rows[0]); + var cardsResponse = rows; // Nest the cards response var cards = D3.nest() @@ -113,7 +112,7 @@ exports.district = function(rows) { 'district_code': d.key.substr(0,4), 'district_name': d.key.substr(4), 'data': d.values.map(function(e) { - return e.values; + return e.value; }) }; }); diff --git a/app/helpers/queries.js b/app/helpers/queries.js index ddcb1860..af4a0b74 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -13,11 +13,11 @@ exports.cards = function(USER_ID, ROLE) { return "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + "SELECT DISTINCT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"');"; } else if (ROLE === 'district') { - return "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, b.days_to_payment, c.current_total, d.delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;"; + return "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, b.days_to_payment, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;"; } }; -exports.performance = function(REGION_CODE, ROLE) { +exports.performance = function(USER_ID, ROLE) { if (ROLE === 'block') { return "SELECT state_code,state_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM state_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.state_code IN (SELECT b.state_code FROM blocks b WHERE b.block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + "SELECT district_code,district_name,SUM(total_transactions) tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),0) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),0) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),0) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),0) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),0) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),0) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),0) sn2_prc FROM district_delays_duration a WHERE a.gender = 'both' AND a.bank_type = 'all' AND a.date_type = 'processed_date' AND a.total_transactions > 0 AND a.district_code IN (SELECT b.district_code FROM blocks b WHERE b.block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) GROUP BY YEAR(date), MONTH(date) ORDER BY date;" + @@ -49,7 +49,7 @@ exports.paydroid = function(USER_ID,ROLE,VERSION) { "SELECT * FROM contact;"; } else if (ROLE=='district') { return "SELECT a.current_total, b.delayed_total, c.days_to_payment FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT a.block_code FROM blocks a RIGHT JOIN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") b ON a.district_code = b.region_code)) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT a.block_code FROM blocks a RIGHT JOIN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") b ON a.district_code = b.region_code)) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment, 1 AS merge FROM district_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + - "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, b.days_to_payment, c.current_total, d.delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;" + + "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, IFNULL(b.days_to_payment,'No Data') AS days_to_payment, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;" + "SELECT district_code, district_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM district_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY district_code, date;" + "SELECT block_code, block_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') ORDER BY block_code, date;" + "SELECT district_code, block_code, panchayat_code, panchayat_name,total_transactions tot_trn,date,ROUND(mrc_mre_mean,1) mrc_mre,ROUND(mre_wlg_mean,1) mre_wlg,ROUND(wlg_wls_mean,1) wlg_wls,ROUND(wls_fto_mean,1) wls_fto,ROUND(fto_firstsign_mean,1) fto_sn1,ROUND(firstsign_secondsign_mean,1) sn1_sn2,ROUND(secondsign_processed_mean,1) sn2_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT a.block_code FROM blocks a RIGHT JOIN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") b ON a.district_code = b.region_code) ORDER BY panchayat_code, date;" + From 881533ea5f34f9b012c8d64878b79ef92ab02c17 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 5 Aug 2016 11:14:49 +0530 Subject: [PATCH 042/314] Cleanup models --- app/models/feedbacks.js | 23 ----------------------- app/models/notifications.js | 29 ----------------------------- app/models/user.js | 2 -- app/models/user_regions.js | 2 +- 4 files changed, 1 insertion(+), 55 deletions(-) delete mode 100644 app/models/feedbacks.js delete mode 100644 app/models/notifications.js diff --git a/app/models/feedbacks.js b/app/models/feedbacks.js deleted file mode 100644 index fe4518ba..00000000 --- a/app/models/feedbacks.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; - -module.exports = function(sequelize, DataTypes) { - var feedbacks = sequelize.define('feedbacks', { - msg: DataTypes.STRING, - region_code: DataTypes.STRING, - notification_id: DataTypes.INTEGER, - }, { - timestamps: true, - underscored: true, - classMethods: { - - associate: function(models) { - // associations can be defined here - feedbacks.belongsTo(models.User, { - onDelete: 'CASCADE', - foreignKey: 'user_id' - }); - } - } - }); - return feedbacks; -}; diff --git a/app/models/notifications.js b/app/models/notifications.js deleted file mode 100644 index 73e98787..00000000 --- a/app/models/notifications.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; - -module.exports = function(sequelize, DataTypes) { - var notifications = sequelize.define('notifications', { - msg: DataTypes.STRING, - region_code: DataTypes.STRING, - notification_type: DataTypes.INTEGER, - viewed: DataTypes.BOOLEAN, - batch_id: DataTypes.INTEGER, - region_name: DataTypes.STRING, - total_transactions: DataTypes.INTEGER, - days_to_payment: DataTypes.INTEGER, - batch_date: DataTypes.DATE - }, { - timestamps: true, - underscored: true, - classMethods: { - - associate: function(models) { - // associations can be defined here - notifications.belongsTo(models.User, { - onDelete: 'CASCADE', - foreignKey: 'user_id', - }); - } - } - }); - return notifications; -}; diff --git a/app/models/user.js b/app/models/user.js index 0f49186a..d91fe42b 100644 --- a/app/models/user.js +++ b/app/models/user.js @@ -33,9 +33,7 @@ module.exports = function(sequelize, DataTypes) { underscored: true, classMethods: { associate: function(models) { - // associations can be defined here User.hasMany(models.user_regions); - User.hasMany(models.notifications); } } }); diff --git a/app/models/user_regions.js b/app/models/user_regions.js index a6e2f411..30d0bb6c 100644 --- a/app/models/user_regions.js +++ b/app/models/user_regions.js @@ -9,7 +9,7 @@ module.exports = function(sequelize, DataTypes) { underscored: true, classMethods: { associate: function(models) { - // associations can be defined here + user_blocks.belongsTo(models.User, { onDelete: 'CASCADE', foreignKey: 'user_id' From 60361cb0277864b4fbd49a2f498625f8a251dc8c Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 5 Aug 2016 13:03:23 +0530 Subject: [PATCH 043/314] Cleaning up for fresh start --- app/routes/auth.js | 2 +- app/routes/overview.js | 7 +- app/routes/performance.js | 5 +- app/templates/alerts/notifications-read.hbs | 18 - app/templates/alerts/notifications-unread.hbs | 19 - app/templates/monitor/analysis.hbs | 8 - app/templates/monitor/server.hbs | 38 - app/templates/monitor/user.hbs | 47 - assets/images/grid.png | Bin 139 -> 0 bytes assets/images/settings.png | Bin 3915 -> 0 bytes assets/misc/favicon.ico | Bin 7094 -> 0 bytes assets/scripts/components/active-link.js | 15 - assets/scripts/components/cards.jsx | 48 - assets/scripts/components/dropdown.js | 327 - assets/scripts/components/region.js | 24 - assets/scripts/index.js | 24 - assets/scripts/lib/chart.js | 170 - assets/scripts/lib/cookie.js | 8 - assets/scripts/lib/metricsgraphics.js | 6013 --------------- assets/scripts/lib/parser.js | 57 - assets/scripts/lib/template.js | 79 - assets/scripts/lib/util.js | 95 - assets/scripts/monitor.js | 4 - assets/scripts/musters/current.js | 33 - assets/scripts/musters/delayed.js | 44 - assets/scripts/performance/discrete.js | 198 - assets/scripts/performance/overview.js | 133 - assets/scripts/vendor/dynatable.js | 1731 ----- assets/scripts/vendor/metricsgraphics.js | 6632 ----------------- assets/styles/base/base.scss | 19 - assets/styles/base/buttons.scss | 76 - assets/styles/base/forms.scss | 116 - assets/styles/base/grid.scss | 678 -- assets/styles/base/lists.scss | 20 - assets/styles/base/spacing.scss | 27 - assets/styles/base/tables.scss | 9 - assets/styles/base/typography.scss | 96 - assets/styles/config/base.scss | 30 - assets/styles/config/color.scss | 33 - assets/styles/config/type.scss | 47 - assets/styles/helpers/placeholders.scss | 7 - assets/styles/helpers/utils.scss | 53 - assets/styles/index.scss | 49 - assets/styles/layout/containers.scss | 33 - assets/styles/layout/metabar.scss | 95 - assets/styles/modules/dropdown.scss | 153 - assets/styles/modules/loader.scss | 64 - assets/styles/modules/menu.scss | 95 - assets/styles/modules/message.scss | 57 - assets/styles/vendors/dynatable.css | 69 - assets/styles/vendors/mg/metricsgraphics.css | 391 - assets/styles/vendors/mg/mg-theme.scss | 240 - assets/styles/vendors/normalize.css | 427 -- assets/styles/vendors/stroke/helper.css | 191 - .../vendors/stroke/pe-icon-7-stroke.css | 632 -- assets/styles/views/dashboard.scss | 153 - assets/styles/views/home.scss | 25 - assets/styles/views/musters.scss | 4 - assets/styles/views/responsive.scss | 90 - config/manifest.js | 5 + 60 files changed, 15 insertions(+), 19748 deletions(-) delete mode 100644 app/templates/alerts/notifications-read.hbs delete mode 100644 app/templates/alerts/notifications-unread.hbs delete mode 100644 app/templates/monitor/analysis.hbs delete mode 100644 app/templates/monitor/server.hbs delete mode 100644 app/templates/monitor/user.hbs delete mode 100644 assets/images/grid.png delete mode 100644 assets/images/settings.png delete mode 100644 assets/misc/favicon.ico delete mode 100644 assets/scripts/components/active-link.js delete mode 100644 assets/scripts/components/cards.jsx delete mode 100644 assets/scripts/components/dropdown.js delete mode 100644 assets/scripts/components/region.js delete mode 100644 assets/scripts/lib/chart.js delete mode 100644 assets/scripts/lib/cookie.js delete mode 100644 assets/scripts/lib/metricsgraphics.js delete mode 100644 assets/scripts/lib/parser.js delete mode 100644 assets/scripts/lib/template.js delete mode 100644 assets/scripts/lib/util.js delete mode 100644 assets/scripts/monitor.js delete mode 100644 assets/scripts/musters/current.js delete mode 100644 assets/scripts/musters/delayed.js delete mode 100644 assets/scripts/performance/discrete.js delete mode 100644 assets/scripts/performance/overview.js delete mode 100755 assets/scripts/vendor/dynatable.js delete mode 100644 assets/scripts/vendor/metricsgraphics.js delete mode 100644 assets/styles/base/base.scss delete mode 100644 assets/styles/base/buttons.scss delete mode 100644 assets/styles/base/forms.scss delete mode 100644 assets/styles/base/grid.scss delete mode 100644 assets/styles/base/lists.scss delete mode 100644 assets/styles/base/spacing.scss delete mode 100644 assets/styles/base/tables.scss delete mode 100644 assets/styles/base/typography.scss delete mode 100644 assets/styles/config/base.scss delete mode 100644 assets/styles/config/color.scss delete mode 100644 assets/styles/config/type.scss delete mode 100644 assets/styles/helpers/placeholders.scss delete mode 100644 assets/styles/helpers/utils.scss delete mode 100644 assets/styles/layout/containers.scss delete mode 100644 assets/styles/layout/metabar.scss delete mode 100644 assets/styles/modules/dropdown.scss delete mode 100644 assets/styles/modules/loader.scss delete mode 100644 assets/styles/modules/menu.scss delete mode 100644 assets/styles/modules/message.scss delete mode 100755 assets/styles/vendors/dynatable.css delete mode 100644 assets/styles/vendors/mg/metricsgraphics.css delete mode 100644 assets/styles/vendors/mg/mg-theme.scss delete mode 100644 assets/styles/vendors/normalize.css delete mode 100644 assets/styles/vendors/stroke/helper.css delete mode 100755 assets/styles/vendors/stroke/pe-icon-7-stroke.css delete mode 100644 assets/styles/views/dashboard.scss delete mode 100644 assets/styles/views/home.scss delete mode 100644 assets/styles/views/musters.scss delete mode 100644 assets/styles/views/responsive.scss diff --git a/app/routes/auth.js b/app/routes/auth.js index 0f5a3388..69ac671f 100644 --- a/app/routes/auth.js +++ b/app/routes/auth.js @@ -11,7 +11,7 @@ exports.register = function(plugin, options, next) { plugin.route([ - // auth Routes + // Auth Routes { method: 'GET', path: '/login', diff --git a/app/routes/overview.js b/app/routes/overview.js index 64451356..f5221056 100644 --- a/app/routes/overview.js +++ b/app/routes/overview.js @@ -8,12 +8,15 @@ exports.register = function(plugin, options, next) { plugin.route([ - // Performance + // Overview { method: 'GET', path: '/overview', config: Controllers.overview.showPage - }, { + }, + + // Overview data + { method: 'GET', path: '/overview/data', config: Controllers.overview.getData diff --git a/app/routes/performance.js b/app/routes/performance.js index 42e33253..65f70065 100644 --- a/app/routes/performance.js +++ b/app/routes/performance.js @@ -13,7 +13,10 @@ exports.register = function(plugin, options, next) { method: 'GET', path: '/performance', config: Controllers.performance.showPage - }, { + }, + + // Performance data + { method: 'GET', path: '/performance/data', config: Controllers.performance.getData diff --git a/app/templates/alerts/notifications-read.hbs b/app/templates/alerts/notifications-read.hbs deleted file mode 100644 index a6e715a3..00000000 --- a/app/templates/alerts/notifications-read.hbs +++ /dev/null @@ -1,18 +0,0 @@ -
    - -
      - {{#each notifications}} -
    • -
        - {{#each this}} -
      • {{msg}}
      • - {{/each}} -
      -
    • - {{/each}} -
    -
    -{{> footer}} diff --git a/app/templates/alerts/notifications-unread.hbs b/app/templates/alerts/notifications-unread.hbs deleted file mode 100644 index 949d15e9..00000000 --- a/app/templates/alerts/notifications-unread.hbs +++ /dev/null @@ -1,19 +0,0 @@ -
    - -
      -
        - {{#each notifications}} -
      • -
          - {{#each this}} -
        • {{msg}}
        • - {{/each}} -
        -
      • - {{/each}} -
      -
    -{{> footer}} diff --git a/app/templates/monitor/analysis.hbs b/app/templates/monitor/analysis.hbs deleted file mode 100644 index 6d700752..00000000 --- a/app/templates/monitor/analysis.hbs +++ /dev/null @@ -1,8 +0,0 @@ -
    - -
    -
    -
    diff --git a/app/templates/monitor/server.hbs b/app/templates/monitor/server.hbs deleted file mode 100644 index f5be0c2f..00000000 --- a/app/templates/monitor/server.hbs +++ /dev/null @@ -1,38 +0,0 @@ -
    - {{!-- CPU Use chart --}} -
    CPU usages
    -
    -
    -
    -
    -
    -
    -
    - {{!-- CPU Use chart --}} -
    Memory usages
    -
    -
    -
    -
    -
    -
    -
    - {{!-- Heap Use chart --}} -
    Heap usages
    -
    -
    -
    -
    -
    -
    -
    - {{!-- Heap Use chart --}} -
    Page Timing Chart
    -
    -
    -
    -
    -
    -
    -
    -
    diff --git a/app/templates/monitor/user.hbs b/app/templates/monitor/user.hbs deleted file mode 100644 index 7ed649be..00000000 --- a/app/templates/monitor/user.hbs +++ /dev/null @@ -1,47 +0,0 @@ -
    - {{!-- Number of Sessions chart --}} -
    User sessions
    -
    -
    -
    -
    -
    -
    -
    - {{!-- Session duration chart --}} -
    Session duration
    -
    -
    -
    -
    -
    -
    -
    - {{!-- Time spent per page chart --}} -
    Time spent
    -
    -
    -
    -
    -
    -
    -
    - {{!-- Time spent per page chart --}} -
    Unique users
    -
    -
    -
    -
    -
    -
    -
    - {{!-- Time spent per page chart --}} -
    Sessions per user
    -
    -
    -
    -
    -
    -
    -
    -
    diff --git a/assets/images/grid.png b/assets/images/grid.png deleted file mode 100644 index afdfa3e17dc1ea3d68b828210eac1d88df991119..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139 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 diff --git a/assets/scripts/components/active-link.js b/assets/scripts/components/active-link.js deleted file mode 100644 index 5fe0d70f..00000000 --- a/assets/scripts/components/active-link.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; -var $ = require('jquery'); -var d3 = require('d3'); - -$('a[href="' + location.pathname + '"]').addClass('active'); - -// MENU -d3.selectAll('#top-ham').on('click', function() { - d3.selectAll('#top-ham').classed('active', function(d, i) { - return !d3.select(this).classed('active'); - }); - d3.selectAll('.menu-wrapper').classed('active', function(d, i) { - return !d3.select(this).classed('active'); - }); -}); diff --git a/assets/scripts/components/cards.jsx b/assets/scripts/components/cards.jsx deleted file mode 100644 index f08d7992..00000000 --- a/assets/scripts/components/cards.jsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react'; -import {render} from 'react-dom'; - -var List = React.createClass({ - render: function(){ - return ( -
      - { - this.props.items.map(function(item) { - return
    • {item}
    • ; - }) - } -
    - ); - } -}); - -var FilteredList = React.createClass({ - filterList: function(event){ - var updatedList = this.state.initialItems; - updatedList = updatedList.filter(function(item){ - return item.toLowerCase().search(event.target.value.toLowerCase()) !== -1; - }); - this.setState({items: updatedList}); - }, - getInitialState: function(){ - return { - initialItems: [ - 'one', - 'two' - ], - items: [] - }; - }, - componentWillMount: function(){ - this.setState({items: this.state.initialItems}); - }, - render: function(){ - return ( -
    - - -
    - ); - } -}); - -render(, document.getElementById('cards')); diff --git a/assets/scripts/components/dropdown.js b/assets/scripts/components/dropdown.js deleted file mode 100644 index c165b033..00000000 --- a/assets/scripts/components/dropdown.js +++ /dev/null @@ -1,327 +0,0 @@ -'use strict'; -var jQuery = require('jquery'); - - -var _createClass = (function() { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ('value' in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - return function(Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; -})(); - -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError('Cannot call a class as a function'); - } -} - -var Dropdown = (function($) { - - /** - * ------------------------------------------------------------------------ - * Constants - * ------------------------------------------------------------------------ - */ - - var NAME = 'dropdown'; - var VERSION = '4.0.0'; - var DATA_KEY = 'bs.dropdown'; - var EVENT_KEY = '.' + DATA_KEY; - var DATA_API_KEY = '.data-api'; - var JQUERY_NO_CONFLICT = $.fn[NAME]; - - var Event = { - HIDE: 'hide' + EVENT_KEY, - HIDDEN: 'hidden' + EVENT_KEY, - SHOW: 'show' + EVENT_KEY, - SHOWN: 'shown' + EVENT_KEY, - CLICK: 'click' + EVENT_KEY, - CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY, - KEYDOWN_DATA_API: 'keydown' + EVENT_KEY + DATA_API_KEY - }; - - var ClassName = { - BACKDROP: 'dropdown-backdrop', - DISABLED: 'disabled', - OPEN: 'open' - }; - - var Selector = { - BACKDROP: '.dropdown-backdrop', - DATA_TOGGLE: '[data-toggle="dropdown"]', - FORM_CHILD: '.dropdown form', - ROLE_MENU: '[role="menu"]', - ROLE_LISTBOX: '[role="listbox"]', - NAVBAR_NAV: '.navbar-nav', - VISIBLE_ITEMS: '[role="menu"] li:not(.disabled) a, ' + '[role="listbox"] li:not(.disabled) a' - }; - - /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ - */ - - var Dropdown = (function() { - function Dropdown(element) { - _classCallCheck(this, Dropdown); - - this._element = element; - - this._addEventListeners(); - } - - /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ - */ - - // getters - - _createClass(Dropdown, [{ - key: 'toggle', - - // public - - value: function toggle() { - if (this.disabled || $(this).hasClass(ClassName.DISABLED)) { - return false; - } - - var parent = Dropdown._getParentFromElement(this); - var isActive = $(parent).hasClass(ClassName.OPEN); - - Dropdown._clearMenus(); - - if (isActive) { - return false; - } - - if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) { - - // if mobile we use a backdrop because click events don't delegate - var dropdown = document.createElement('div'); - dropdown.className = ClassName.BACKDROP; - $(dropdown).insertBefore(this); - $(dropdown).on('click', Dropdown._clearMenus); - } - - var relatedTarget = { - relatedTarget: this - }; - var showEvent = $.Event(Event.SHOW, relatedTarget); - - $(parent).trigger(showEvent); - - if (showEvent.isDefaultPrevented()) { - return false; - } - - this.focus(); - this.setAttribute('aria-expanded', 'true'); - - $(parent).toggleClass(ClassName.OPEN); - $(parent).trigger($.Event(Event.SHOWN, relatedTarget)); - - return false; - } - }, { - key: 'dispose', - value: function dispose() { - $.removeData(this._element, DATA_KEY); - $(this._element).off(EVENT_KEY); - this._element = null; - } - - // private - - }, { - key: '_addEventListeners', - value: function _addEventListeners() { - $(this._element).on(Event.CLICK, this.toggle); - } - - // static - - }], [{ - key: '_jQueryInterface', - value: function _jQueryInterface(config) { - return this.each(function() { - var data = $(this).data(DATA_KEY); - - if (!data) { - $(this).data(DATA_KEY, data = new Dropdown(this)); - } - - if (typeof config === 'string') { - data[config].call(this); - } - }); - } - }, { - key: '_clearMenus', - value: function _clearMenus(event) { - if (event && event.which === 3) { - return; - } - - var backdrop = $(Selector.BACKDROP)[0]; - if (backdrop) { - backdrop.parentNode.removeChild(backdrop); - } - - var toggles = $.makeArray($(Selector.DATA_TOGGLE)); - - for (var i = 0; i < toggles.length; i++) { - var _parent = Dropdown._getParentFromElement(toggles[i]); - var relatedTarget = { - relatedTarget: toggles[i] - }; - - if (!$(_parent).hasClass(ClassName.OPEN)) { - continue; - } - - if (event && event.type === 'click' && /input|textarea/i.test(event.target.tagName) && $.contains(_parent, event.target)) { - continue; - } - - var hideEvent = $.Event(Event.HIDE, relatedTarget); - $(_parent).trigger(hideEvent); - if (hideEvent.isDefaultPrevented()) { - continue; - } - - toggles[i].setAttribute('aria-expanded', 'false'); - - $(_parent).removeClass(ClassName.OPEN).trigger($.Event(Event.HIDDEN, relatedTarget)); - } - } - }, { - key: '_getParentFromElement', - value: function _getParentFromElement(element) { - var parent; - - function getSelectorFromElement(element) { - var selector = element.getAttribute('data-target'); - if (!selector) { - selector = element.getAttribute('href') || ''; - selector = /^#[a-z]/i.test(selector) ? selector : null; - } - return selector; - } - - var selector = getSelectorFromElement(element); - - if (selector) { - parent = $(selector)[0]; - } - - return parent || element.parentNode; - } - }, { - key: '_dataApiKeydownHandler', - value: function _dataApiKeydownHandler(event) { - if (!/(38|40|27|32)/.test(event.which) || /input|textarea/i.test(event.target.tagName)) { - return; - } - - event.preventDefault(); - event.stopPropagation(); - - if (this.disabled || $(this).hasClass(ClassName.DISABLED)) { - return; - } - - var parent = Dropdown._getParentFromElement(this); - var isActive = $(parent).hasClass(ClassName.OPEN); - - if (!isActive && event.which !== 27 || isActive && event.which === 27) { - - if (event.which === 27) { - var toggle = $(parent).find(Selector.DATA_TOGGLE)[0]; - $(toggle).trigger('focus'); - } - - $(this).trigger('click'); - return; - } - - var items = $.makeArray($(Selector.VISIBLE_ITEMS)); - - items = items.filter(function(item) { - return item.offsetWidth || item.offsetHeight; - }); - - if (!items.length) { - return; - } - - var index = items.indexOf(event.target); - - if (event.which === 38 && index > 0) { - // up - index--; - } - - if (event.which === 40 && index < items.length - 1) { - // down - index++; - } - - if (!~index) { - index = 0; - } - - items[index].focus(); - } - }, { - key: 'VERSION', - get: function get() { - return VERSION; - } - }]); - - return Dropdown; - })(); - - $(document).on( - Event.KEYDOWN_DATA_API, - Selector.DATA_TOGGLE, - Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, - Selector.ROLE_MENU, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, - Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API, - Dropdown._clearMenus).on(Event.CLICK_DATA_API, - Selector.DATA_TOGGLE, Dropdown.prototype.toggle).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, - function(e) { - e.stopPropagation(); - }); - - /** - * ------------------------------------------------------------------------ - * jQuery - * ------------------------------------------------------------------------ - */ - - $.fn[NAME] = Dropdown._jQueryInterface; - $.fn[NAME].Constructor = Dropdown; - $.fn[NAME].noConflict = function() { - $.fn[NAME] = JQUERY_NO_CONFLICT; - return Dropdown._jQueryInterface; - }; - - return Dropdown; -})(jQuery); - -module.exports = Dropdown; diff --git a/assets/scripts/components/region.js b/assets/scripts/components/region.js deleted file mode 100644 index a7a4a248..00000000 --- a/assets/scripts/components/region.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict'; - -var $ = require('jquery'); -var Cookie = require('../lib/cookie'); - -var active_region = Cookie.read('active_region'); - -if (active_region) { - $('#region_selector option[value="' + active_region + '"]').attr('selected', 'selected'); -} else { - setCookie($('#region_selector option')[0].value); - location.reload(); -} - -// Set cookie on change -$('#region_selector').on('change', function(ele) { - setCookie(ele.target.value); - location.reload(); -}); - - -function setCookie(value) { - document.cookie = 'active_region=' + value + ';Path=/;'; -} diff --git a/assets/scripts/index.js b/assets/scripts/index.js index 16640242..e69de29b 100644 --- a/assets/scripts/index.js +++ b/assets/scripts/index.js @@ -1,24 +0,0 @@ -'use strict'; - -require('./components/dropdown'); -require('./components/region'); -require('./components/active-link'); - -var OverviewPerformance = require('./performance/overview'); -var DiscretePerformance = require('./performance/discrete'); - -if (window.location.pathname === '/performance/overview') { - OverviewPerformance.init(); -} -if (window.location.pathname === '/performance/discrete') { - DiscretePerformance.init(); -} - -if (window.location.pathname === '/musters/current') { - - require('./components/cards.jsx'); -} - -if (window.location.pathname === '/login') { - document.cookie = 'active_region=;Path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT;'; -} diff --git a/assets/scripts/lib/chart.js b/assets/scripts/lib/chart.js deleted file mode 100644 index b2a97c74..00000000 --- a/assets/scripts/lib/chart.js +++ /dev/null @@ -1,170 +0,0 @@ -'use strict'; - -var D3 = require('d3'); -var MG = require('./metricsgraphics'); - -exports.flash = function(options) { - MG.data_graphic({ - title: '', - data: options.data, - target: options.target, - width: 600, - height: 500, - left: 100, - full_width: true, - // transition_on_update: true, - show_secondary_x_label: false, - x_extended_ticks: true, - xax_count: 5, - xax_format: D3.time.format('%e %b, %y'), - decimals: 0, - baselines: [{ - value: 15, - label: 'Statutory Limit' - }], - point_size : 3.5, - max_x : options.max_x || null, - min_x: options.min_x || null, - chart_type: options.data.length !== 0 ? 'line' : 'missing-data', - missing_text: 'No data', - legend: options.labels, - legend_target: options.legend_target, - aggregate_rollover: true, - show_tooltips: false, - interplate: 'linear', - interpolate_tension: .98, - area: options.area, - y_label: options.y_axis_label, - mouseover: function(d, i) { - if (!d.values) { - d.values = [d]; - } - if (options.data.length) { - for (i = 1; i <= options.data.length; i++) { - var l_span = D3.select(options.legend_target + ' .mg-line' + i + '-legend-color'); - l_span.text(' '); - l_span.text('— ' + options.labels[i - 1]); - } - } - d.values.forEach(function(val, index) { - var l_span = D3.select(options.legend_target + ' .mg-line' + val.line_id + '-legend-color'); - l_span.text(' '); - var no_days = d.values[index - 1] ? (val.value - d.values[index - 1].value).toFixed(0) : (val.value).toFixed(0); - l_span.text('— ' + options.labels[val.line_id - 1] + ' : ' + no_days); - var format = D3.time.format('%b %d, %Y'); - D3.select(options.target + '_total_trans').text(format(val.date) + ': ' + val.total_trans); - }); - }, - mouseout: function(d, i) { - if (!d.values) { - d.values = [d]; - } - D3.select(options.target + '_total_trans').text(''); - d.values.forEach(function(val, index) { - var l_span = D3.select(options.legend_target + ' .mg-line' + val.line_id + '-legend-color'); - l_span.text(' '); - l_span.text('— ' + options.labels[index]); - }); - } - }); -}; - -exports.singular = function(options) { - - MG.data_graphic({ - // title: options.title, - title: '', - data: options.data, - width: 600, - height: 500, - left: 100, - full_width: true, - decimals: 0, - target: options.target, - xax_count: 10, - max_x : options.max_x || null, - min_x: options.min_x || null, - xax_format: D3.time.format('%b, %y'), - chart_type: options.data.length !== 0 ? 'line' : 'missing-data', - missing_text: 'No data', - show_secondary_x_label: false, - x_extended_ticks: true, - legend: options.labels, - legend_target: options.legend_target, - show_tooltips: false, - aggregate_rollover: true, - show_year_markers: true, - point_size : 3.5, - // transition_on_update: true, - interplate: 'linear', - interpolate_tension: 1, - area: options.area, - y_label: options.y_axis_label, - show_rollover_text: false, - mouseover: function(d, i) { - if (!d.values) { - d.values = [d]; - } - if (options.data.length) { - for (i = 1; i <= options.data.length; i++) { - var l_span = D3.select(options.legend_target + ' .mg-line' + i + '-legend-color'); - l_span.text(' '); - l_span.text('— ' + options.labels[i - 1]); - } - } - d.values.forEach(function(val, index) { - var prefix = D3.formatPrefix(val.value); - var l_span = D3.select(options.legend_target + ' .mg-line' + val.line_id + '-legend-color'); - l_span.text(' '); - l_span.text('— ' + options.labels[val.line_id - 1] + ' : ' + prefix.scale(val.value).toFixed(0)); - var format = D3.time.format('%b, %Y'); - D3.select(options.target + '_total_trans').text(format(val.date) + ': ' + val.total_trans); - }); - }, - mouseout: function(d, i) { - if (!d.values) { - d.values = [d]; - } - D3.select(options.target + '_total_trans').text(''); - d.values.forEach(function(val, index) { - var l_span = D3.select(options.legend_target + ' .mg-line' + val.line_id + '-legend-color'); - l_span.text(' '); - l_span.text('— ' + options.labels[val.line_id - 1]); - }); - } - }); -}; - -exports.small = function(options) { - MG.data_graphic({ - title: options.title, - data: options.data, - width: 295, - height: 300, - right: 10, - left: 90, - small_text: true, - xax_count: 3, - decimals: 0, - xax_format: D3.time.format('%e %b, %y'), - chart_type: options.data.length !== 0 ? 'line' : 'missing-data', - missing_text: 'No data', - target: options.target, - legend: options.labels, - legend_target: options.legend_target, - full_width: true, - point_size : 3.5, - aggregate_rollover: true, - x_extended_ticks: true, - transition_on_update: false, - max_y: options.max_y || undefined, - interplate: 'linear', - linked: true, - interpolate_tension: 1, - y_label: 'Days to Complete Process', - area: options.area, - show_secondary_x_label: false, - max_x: options.max_x || undefined, - min_x: options.min_x || undefined - }); -}; diff --git a/assets/scripts/lib/cookie.js b/assets/scripts/lib/cookie.js deleted file mode 100644 index f6d499e5..00000000 --- a/assets/scripts/lib/cookie.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - - -// Setup cookie for block selection -exports.read = function(key) { - var result; - return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? (result[1]) : null; -}; diff --git a/assets/scripts/lib/metricsgraphics.js b/assets/scripts/lib/metricsgraphics.js deleted file mode 100644 index 614f986f..00000000 --- a/assets/scripts/lib/metricsgraphics.js +++ /dev/null @@ -1,6013 +0,0 @@ -(function(root, factory) { - if (typeof define === 'function' && define.amd) { - define(['d3', 'jquery'], factory); - } else if (typeof exports === 'object') { - module.exports = factory(require('d3'), require('jquery')); - } else { - root.MG = factory(root.d3, root.jQuery); - } -}(this, function(d3, $) { -window.MG = {version: '2.7.0'}; - -function register(chartType, descriptor, defaults) { - MG.charts[chartType] = { - descriptor: descriptor, - defaults: defaults || {} - }; -} - -MG.register = register; - -/** - Record of all registered hooks. - For internal use only. -*/ -MG._hooks = {}; - -/** - Add a hook callthrough to the stack. - - Hooks are executed in the order that they were registered. -*/ -MG.add_hook = function(name, func, context) { - var hooks; - - if (!MG._hooks[name]) { - MG._hooks[name] = []; - } - - hooks = MG._hooks[name]; - - var already_registered = - hooks.filter(function(hook) { - return hook.func === func; - }) - .length > 0; - - if (already_registered) { - throw 'That function is already registered.'; - } - - hooks.push({ - func: func, - context: context - }); -}; - -/** - Execute registered hooks. - - Optional arguments -*/ -MG.call_hook = function(name) { - var hooks = MG._hooks[name], - result = [].slice.apply(arguments, [1]), - processed; - - if (hooks) { - hooks.forEach(function(hook) { - if (hook.func) { - var params = processed || result; - - if (params && params.constructor !== Array) { - params = [params]; - } - - params = [].concat.apply([], params); - processed = hook.func.apply(hook.context, params); - } - }); - } - - return processed || result; -}; - -MG.globals = {}; -MG.deprecations = { - rollover_callback: { replacement: 'mouseover', version: '2.0' }, - rollout_callback: { replacement: 'mouseout', version: '2.0' }, - x_rollover_format: { replacement: 'x_mouseover', version: '2.10' }, - y_rollover_format: { replacement: 'y_mouseover', version: '2.10' }, - show_years: { replacement: 'show_secondary_x_label', version: '2.1' }, - xax_start_at_min: { replacement: 'axes_not_compact', version: '2.7' } -}; -MG.globals.link = false; -MG.globals.version = "1.1"; - -MG.charts = {}; - -MG.data_graphic = function(args) { - 'use strict'; - var defaults = { - missing_is_zero: false, // if true, missing values will be treated as zeros - missing_is_hidden: false, // if true, missing values will appear as broken segments - missing_is_hidden_accessor: null, // the accessor that determines the boolean value for missing data points - legend: '' , // an array identifying the labels for a chart's lines - legend_target: '', // if set, the specified element is populated with a legend - error: '', // if set, a graph will show an error icon and log the error to the console - animate_on_load: false, // animate lines on load - top: 65, // the size of the top margin - title_y_position: 10, // how many pixels from the top edge (0) should we show the title at - bottom: 30, // the size of the bottom margin - right: 10, // size of the right margin - left: 50, // size of the left margin - buffer: 8, // the buffer between the actual chart area and the margins - width: 350, // the width of the entire graphic - height: 220, // the height of the entire graphic - full_width: false, // sets the graphic width to be the width of the parent element and resizes dynamically - full_height: false, // sets the graphic width to be the width of the parent element and resizes dynamically - small_height_threshold: 120, // the height threshold for when smaller text appears - small_width_threshold: 160, // the width threshold for when smaller text appears - //small_text: false, // coerces small text regardless of graphic size - xax_count: 6, // number of x axis ticks - xax_tick_length: 5, // x axis tick length - axes_not_compact: true, - yax_count: 5, // number of y axis ticks - yax_tick_length: 5, // y axis tick length - x_extended_ticks: false, // extends x axis ticks across chart - useful for tall charts - y_extended_ticks: false, // extends y axis ticks across chart - useful for long charts - y_scale_type: 'linear', - max_x: null, - max_y: null, - min_x: null, - min_y: null, // if set, y axis starts at an arbitrary value - min_y_from_data: false, // if set, y axis will start at minimum value rather than at 0 - point_size: 2.5, // the size of the dot that appears on a line on mouse-over - x_accessor: 'date', - xax_units: '', - x_label: '', - x_sort: true, - x_axis: true, - y_axis: true, - y_accessor: 'value', - y_label: '', - yax_units: '', - x_rug: false, - y_rug: false, - x_mouseover: null, - y_mouseover: null, - transition_on_update: true, - mouseover: null, - click: null, - show_rollover_text: true, - show_confidence_band: null, // given [l, u] shows a confidence at each point from l to u - xax_format: null, // xax_format is a function that formats the labels for the x axis. - area: true, - chart_type: 'line', - data: [], - decimals: 2, // the number of decimals in any rollover - format: 'count', // format = {count, percentage} - inflator: 10/9, // for setting y axis max - linked: false, // links together all other graphs with linked:true, so rollovers in one trigger rollovers in the others - linked_format: '%Y-%m-%d', // What granularity to link on for graphs. Default is at day - list: false, - baselines: null, // sets the baseline lines - markers: null, // sets the marker lines - scalefns: {}, - scales: {}, - utc_time: false, - european_clock: false, - show_year_markers: false, - show_secondary_x_label: true, - target: '#viz', - interpolate: 'cardinal', // interpolation method to use when rendering lines - interpolate_tension: 0.7, // its range is from 0 to 1; increase if your data is irregular and you notice artifacts - custom_line_color_map: [], // allows arbitrary mapping of lines to colors, e.g. [2,3] will map line 1 to color 2 and line 2 to color 3 - colors: null, // UNIMPLEMENTED - allows direct color mapping to line colors. Will eventually require - max_data_size: null, // explicitly specify the the max number of line series, for use with custom_line_color_map - aggregate_rollover: false, // links the lines in a multi-line chart - show_tooltips: true // if enabled, a chart's description will appear in a tooltip (requires jquery) - }; - - MG.call_hook('global.defaults', defaults); - - if (!args) { args = {}; } - - var selected_chart = MG.charts[args.chart_type || defaults.chart_type]; - merge_with_defaults(args, selected_chart.defaults, defaults); - - if (args.list) { - args.x_accessor = 0; - args.y_accessor = 1; - } - - // check for deprecated parameters - for (var key in MG.deprecations) { - if (args.hasOwnProperty(key)) { - var deprecation = MG.deprecations[key], - message = 'Use of `args.' + key + '` has been deprecated', - replacement = deprecation.replacement, - version; - - // transparently alias the deprecated - if (replacement) { - if (args[replacement]) { - message += '. The replacement - `args.' + replacement + '` - has already been defined. This definition will be discarded.'; - } else { - args[replacement] = args[key]; - } - } - - if (deprecation.warned) { - continue; - } - - deprecation.warned = true; - - if (replacement) { - message += ' in favor of `args.' + replacement + '`'; - } - - warn_deprecation(message, deprecation.version); - } - } - - MG.call_hook('global.before_init', args); - - new selected_chart.descriptor(args); - - return args.data; -}; - -if (typeof jQuery !== 'undefined') { - /* ======================================================================== - * Bootstrap: tooltip.js v3.3.5 - * http://getbootstrap.com/javascript/#tooltip - * Inspired by the original jQuery.tipsy by Jason Frame - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - - +function ($) { - 'use strict'; - - // TOOLTIP PUBLIC CLASS DEFINITION - // =============================== - - var Tooltip = function (element, options) { - this.type = null - this.options = null - this.enabled = null - this.timeout = null - this.hoverState = null - this.$element = null - this.inState = null - - this.init('tooltip', element, options) - } - - Tooltip.VERSION = '3.3.5' - - Tooltip.TRANSITION_DURATION = 150 - - Tooltip.DEFAULTS = { - animation: true, - placement: 'top', - selector: false, - template: '', - trigger: 'hover focus', - title: '', - delay: 0, - html: false, - container: false, - viewport: { - selector: 'body', - padding: 0 - } - } - - Tooltip.prototype.init = function (type, element, options) { - this.enabled = true - this.type = type - this.$element = $(element) - this.options = this.getOptions(options) - this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) - this.inState = { click: false, hover: false, focus: false } - - if (this.$element[0] instanceof document.constructor && !this.options.selector) { - throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') - } - - var triggers = this.options.trigger.split(' ') - - for (var i = triggers.length; i--;) { - var trigger = triggers[i] - - if (trigger == 'click') { - this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) - } else if (trigger != 'manual') { - var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' - var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' - - this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) - this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) - } - } - - this.options.selector ? - (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : - this.fixTitle() - } - - Tooltip.prototype.getDefaults = function () { - return Tooltip.DEFAULTS - } - - Tooltip.prototype.getOptions = function (options) { - options = $.extend({}, this.getDefaults(), this.$element.data(), options) - - if (options.delay && typeof options.delay == 'number') { - options.delay = { - show: options.delay, - hide: options.delay - } - } - - return options - } - - Tooltip.prototype.getDelegateOptions = function () { - var options = {} - var defaults = this.getDefaults() - - this._options && $.each(this._options, function (key, value) { - if (defaults[key] != value) options[key] = value - }) - - return options - } - - Tooltip.prototype.enter = function (obj) { - var self = obj instanceof this.constructor ? - obj : $(obj.currentTarget).data('bs.' + this.type) - - if (!self) { - self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) - $(obj.currentTarget).data('bs.' + this.type, self) - } - - if (obj instanceof $.Event) { - self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true - } - - if (self.tip().hasClass('in') || self.hoverState == 'in') { - self.hoverState = 'in' - return - } - - clearTimeout(self.timeout) - - self.hoverState = 'in' - - if (!self.options.delay || !self.options.delay.show) return self.show() - - self.timeout = setTimeout(function () { - if (self.hoverState == 'in') self.show() - }, self.options.delay.show) - } - - Tooltip.prototype.isInStateTrue = function () { - for (var key in this.inState) { - if (this.inState[key]) return true - } - - return false - } - - Tooltip.prototype.leave = function (obj) { - var self = obj instanceof this.constructor ? - obj : $(obj.currentTarget).data('bs.' + this.type) - - if (!self) { - self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) - $(obj.currentTarget).data('bs.' + this.type, self) - } - - if (obj instanceof $.Event) { - self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false - } - - if (self.isInStateTrue()) return - - clearTimeout(self.timeout) - - self.hoverState = 'out' - - if (!self.options.delay || !self.options.delay.hide) return self.hide() - - self.timeout = setTimeout(function () { - if (self.hoverState == 'out') self.hide() - }, self.options.delay.hide) - } - - Tooltip.prototype.show = function () { - var e = $.Event('show.bs.' + this.type) - - if (this.hasContent() && this.enabled) { - this.$element.trigger(e) - - var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) - if (e.isDefaultPrevented() || !inDom) return - var that = this - - var $tip = this.tip() - - var tipId = this.getUID(this.type) - - this.setContent() - $tip.attr('id', tipId) - this.$element.attr('aria-describedby', tipId) - - if (this.options.animation) $tip.addClass('fade') - - var placement = typeof this.options.placement == 'function' ? - this.options.placement.call(this, $tip[0], this.$element[0]) : - this.options.placement - - var autoToken = /\s?auto?\s?/i - var autoPlace = autoToken.test(placement) - if (autoPlace) placement = placement.replace(autoToken, '') || 'top' - - $tip - .detach() - .css({ top: 0, left: 0, display: 'block' }) - .addClass(placement) - .data('bs.' + this.type, this) - - this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) - this.$element.trigger('inserted.bs.' + this.type) - - var pos = this.getPosition() - var actualWidth = $tip[0].offsetWidth - var actualHeight = $tip[0].offsetHeight - - if (autoPlace) { - var orgPlacement = placement - var viewportDim = this.getPosition(this.$viewport) - - placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : - placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : - placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : - placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : - placement - - $tip - .removeClass(orgPlacement) - .addClass(placement) - } - - var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) - - this.applyPlacement(calculatedOffset, placement) - - var complete = function () { - var prevHoverState = that.hoverState - that.$element.trigger('shown.bs.' + that.type) - that.hoverState = null - - if (prevHoverState == 'out') that.leave(that) - } - - $.support.transition && this.$tip.hasClass('fade') ? - $tip - .one('bsTransitionEnd', complete) - .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : - complete() - } - } - - Tooltip.prototype.applyPlacement = function (offset, placement) { - var $tip = this.tip() - var width = $tip[0].offsetWidth - var height = $tip[0].offsetHeight - - // manually read margins because getBoundingClientRect includes difference - var marginTop = parseInt($tip.css('margin-top'), 10) - var marginLeft = parseInt($tip.css('margin-left'), 10) - - // we must check for NaN for ie 8/9 - if (isNaN(marginTop)) marginTop = 0 - if (isNaN(marginLeft)) marginLeft = 0 - - offset.top += marginTop - offset.left += marginLeft - - // $.fn.offset doesn't round pixel values - // so we use setOffset directly with our own function B-0 - $.offset.setOffset($tip[0], $.extend({ - using: function (props) { - $tip.css({ - top: Math.round(props.top), - left: Math.round(props.left) - }) - } - }, offset), 0) - - $tip.addClass('in') - - // check to see if placing tip in new offset caused the tip to resize itself - var actualWidth = $tip[0].offsetWidth - var actualHeight = $tip[0].offsetHeight - - if (placement == 'top' && actualHeight != height) { - offset.top = offset.top + height - actualHeight - } - - var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) - - if (delta.left) offset.left += delta.left - else offset.top += delta.top - - var isVertical = /top|bottom/.test(placement) - var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight - var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' - - $tip.offset(offset) - this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) - } - - Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { - this.arrow() - .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') - .css(isVertical ? 'top' : 'left', '') - } - - Tooltip.prototype.setContent = function () { - var $tip = this.tip() - var title = this.getTitle() - - $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) - $tip.removeClass('fade in top bottom left right') - } - - Tooltip.prototype.hide = function (callback) { - var that = this - var $tip = $(this.$tip) - var e = $.Event('hide.bs.' + this.type) - - function complete() { - if (that.hoverState != 'in') $tip.detach() - that.$element - .removeAttr('aria-describedby') - .trigger('hidden.bs.' + that.type) - callback && callback() - } - - this.$element.trigger(e) - - if (e.isDefaultPrevented()) return - - $tip.removeClass('in') - - $.support.transition && $tip.hasClass('fade') ? - $tip - .one('bsTransitionEnd', complete) - .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : - complete() - - this.hoverState = null - - return this - } - - Tooltip.prototype.fixTitle = function () { - var $e = this.$element - if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { - $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') - } - } - - Tooltip.prototype.hasContent = function () { - return this.getTitle() - } - - Tooltip.prototype.getPosition = function ($element) { - $element = $element || this.$element - - var el = $element[0] - var isBody = el.tagName == 'BODY' - - var elRect = el.getBoundingClientRect() - if (elRect.width == null) { - // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 - elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) - } - var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() - var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } - var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null - - return $.extend({}, elRect, scroll, outerDims, elOffset) - } - - Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { - return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : - placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : - placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : - /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } - - } - - Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { - var delta = { top: 0, left: 0 } - if (!this.$viewport) return delta - - var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 - var viewportDimensions = this.getPosition(this.$viewport) - - if (/right|left/.test(placement)) { - var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll - var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight - if (topEdgeOffset < viewportDimensions.top) { // top overflow - delta.top = viewportDimensions.top - topEdgeOffset - } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow - delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset - } - } else { - var leftEdgeOffset = pos.left - viewportPadding - var rightEdgeOffset = pos.left + viewportPadding + actualWidth - if (leftEdgeOffset < viewportDimensions.left) { // left overflow - delta.left = viewportDimensions.left - leftEdgeOffset - } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow - delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset - } - } - - return delta - } - - Tooltip.prototype.getTitle = function () { - var title - var $e = this.$element - var o = this.options - - title = $e.attr('data-original-title') - || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) - - return title - } - - Tooltip.prototype.getUID = function (prefix) { - do prefix += ~~(Math.random() * 1000000) - while (document.getElementById(prefix)) - return prefix - } - - Tooltip.prototype.tip = function () { - if (!this.$tip) { - this.$tip = $(this.options.template) - if (this.$tip.length != 1) { - throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') - } - } - return this.$tip - } - - Tooltip.prototype.arrow = function () { - return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) - } - - Tooltip.prototype.enable = function () { - this.enabled = true - } - - Tooltip.prototype.disable = function () { - this.enabled = false - } - - Tooltip.prototype.toggleEnabled = function () { - this.enabled = !this.enabled - } - - Tooltip.prototype.toggle = function (e) { - var self = this - if (e) { - self = $(e.currentTarget).data('bs.' + this.type) - if (!self) { - self = new this.constructor(e.currentTarget, this.getDelegateOptions()) - $(e.currentTarget).data('bs.' + this.type, self) - } - } - - if (e) { - self.inState.click = !self.inState.click - if (self.isInStateTrue()) self.enter(self) - else self.leave(self) - } else { - self.tip().hasClass('in') ? self.leave(self) : self.enter(self) - } - } - - Tooltip.prototype.destroy = function () { - var that = this - clearTimeout(this.timeout) - this.hide(function () { - that.$element.off('.' + that.type).removeData('bs.' + that.type) - if (that.$tip) { - that.$tip.detach() - } - that.$tip = null - that.$arrow = null - that.$viewport = null - }) - } - - - // TOOLTIP PLUGIN DEFINITION - // ========================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.tooltip') - var options = typeof option == 'object' && option - - if (!data && /destroy|hide/.test(option)) return - if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.tooltip - - $.fn.tooltip = Plugin - $.fn.tooltip.Constructor = Tooltip - - - // TOOLTIP NO CONFLICT - // =================== - - $.fn.tooltip.noConflict = function () { - $.fn.tooltip = old - return this - } - - }(jQuery); - - - /* ======================================================================== - * Bootstrap: popover.js v3.3.5 - * http://getbootstrap.com/javascript/#popovers - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - - +function ($) { - 'use strict'; - - // POPOVER PUBLIC CLASS DEFINITION - // =============================== - - var Popover = function (element, options) { - this.init('popover', element, options) - } - - if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') - - Popover.VERSION = '3.3.5' - - Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { - placement: 'right', - trigger: 'click', - content: '', - template: '' - }) - - - // NOTE: POPOVER EXTENDS tooltip.js - // ================================ - - Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) - - Popover.prototype.constructor = Popover - - Popover.prototype.getDefaults = function () { - return Popover.DEFAULTS - } - - Popover.prototype.setContent = function () { - var $tip = this.tip() - var title = this.getTitle() - var content = this.getContent() - - $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) - $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events - this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' - ](content) - - $tip.removeClass('fade top bottom left right in') - - // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do - // this manually by checking the contents. - if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() - } - - Popover.prototype.hasContent = function () { - return this.getTitle() || this.getContent() - } - - Popover.prototype.getContent = function () { - var $e = this.$element - var o = this.options - - return $e.attr('data-content') - || (typeof o.content == 'function' ? - o.content.call($e[0]) : - o.content) - } - - Popover.prototype.arrow = function () { - return (this.$arrow = this.$arrow || this.tip().find('.arrow')) - } - - - // POPOVER PLUGIN DEFINITION - // ========================= - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.popover') - var options = typeof option == 'object' && option - - if (!data && /destroy|hide/.test(option)) return - if (!data) $this.data('bs.popover', (data = new Popover(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.popover - - $.fn.popover = Plugin - $.fn.popover.Constructor = Popover - - - // POPOVER NO CONFLICT - // =================== - - $.fn.popover.noConflict = function () { - $.fn.popover = old - return this - } - - }(jQuery); -} -function chart_title(args) { - 'use strict'; - - var svg = mg_get_svg_child_of(args.target); - - // remove the current title, and its associated event listeners, if it exists - if (args.show_tooltips && args.description) { - $('.mg-header').remove(); - } else { - mg_remove_element(svg, '.mg-header'); - } - - // add the title - if (args.target && args.title) { - var chartTitle = svg.insert('text') - .attr('class', 'mg-header') - .attr('x', (args.width + args.left - args.right) / 2) - .attr('y', args.title_y_position) - .attr('text-anchor', 'middle') - .attr('dy', '0.55em'); - - // show the title - chartTitle.append('tspan') - .attr('class', 'mg-chart-title') - .text(args.title); - - // show and activate the description icon if we have a description - if (args.show_tooltips && args.description) { - chartTitle.append('tspan') - .attr('class', 'mg-chart-description') - .attr('dx', '0.3em') - .text('\uf059'); - - // now that the title is an svg text element, we'll have to trigger - // mouseenter, mouseleave events manually for the popover to work properly - $(chartTitle.node()).popover({ - html: true, - animation: false, - placement: 'top', - content: args.description, - container: args.target, - trigger: 'manual', - template: '

    ' - }).on('mouseenter', function() { - d3.selectAll(args.target) - .selectAll('.mg-popover') - .remove(); - - $(this).popover('show'); - $(args.target).select('.popover') - .on('mouseleave', function () { - $chartTitle.popover('hide'); - }); - }).on('mouseleave', function () { - setTimeout(function () { - if (!$('.popover:hover').length) { - $chartTitle.popover('hide'); - } - }, 120); - }); - } - - chartTitle = null; - } - - if (args.error) { - error(args); - } -} - -MG.chart_title = chart_title; - -function y_rug (args) { - 'use strict'; - args.rug_buffer_size = args.chart_type === 'point' - ? args.buffer / 2 - : args.buffer * 2 / 3; - - var rug = mg_make_rug(args, 'mg-y-rug'); - - rug.attr('x1', args.left + 1) - .attr('x2', args.left + args.rug_buffer_size) - .attr('y1', args.scalefns.yf) - .attr('y2', args.scalefns.yf); - - mg_add_color_accessor_to_rug(rug, args, 'mg-y-rug-mono'); -} - -MG.y_rug = y_rug; - -function mg_change_y_extents_for_bars (args, my) { - if (args.chart_type === 'bar') { - my.min = 0; - my.max = d3.max(args.data[0], function (d) { - var trio = []; - trio.push(d[args.y_accessor]); - - if (args.baseline_accessor !== null) { - trio.push(d[args.baseline_accessor]); - } - - if (args.predictor_accessor !== null) { - trio.push(d[args.predictor_accessor]); - } - - return Math.max.apply(null, trio); - }); - } - return my; -} - -function mg_compute_yax_format (args) { - var yax_format = args.yax_format; - if (!yax_format) { - if (args.format === 'count') { - // increase decimals if we have small values, useful for realtime data - if (args.processed.max_y < 0.0001) { - args.decimals = 6; - } else if (args.processed.max_y < 0.1) { - args.decimals = 4; - } - - yax_format = function (f) { - if (f < 1.0) { - // Don't scale tiny values. - return args.yax_units + d3.round(f, args.decimals); - } else { - var pf = d3.formatPrefix(f); - return args.yax_units + pf.scale(f) + pf.symbol; - } - }; - } else { // percentage - yax_format = function (d_) { - var n = d3.format('2p'); - return n(d_); - }; - } - } - return yax_format; -} - -function set_min_max_y (args) { - // flatten data - // remove weird data, if log. - var data = mg_flatten_array(args.data); - if (args.y_scale_type === 'log') data = data.filter(function (d) { return d[args.y_accessor] > 0; }); - if (args.baselines) { data = data.concat(args.baselines); } - - var extents = d3.extent(data, function (d) { return d[args.y_accessor]; }); - - var my = {}; - my.min = extents[0]; - my.max = extents[1]; - // the default case is for the y-axis to start at 0, unless we explicitly want it - // to start at an arbitrary number or from the data's minimum value - if (my.min >= 0 && !args.min_y && !args.min_y_from_data) { - my.min = 0; - } - - mg_change_y_extents_for_bars(args, my); - my.min = (args.min_y !== null) - ? args.min_y - : my.min; - - my.max = (args.max_y !== null) - ? args.max_y - : (my.max < 0) - ? my.max + (my.max - my.max * args.inflator) - : my.max * args.inflator; - - if (args.y_scale_type !== 'log' && my.min < 0) { - my.min = my.min - (my.min - my.min * args.inflator); - } - - if (!args.min_y && args.min_y_from_data) { - my.min = my.min / args.inflator; - } - args.processed.min_y = my.min; - args.processed.max_y = my.max; -} - -function mg_y_domain_range (args, scale) { - scale.domain([args.processed.min_y, args.processed.max_y]) - .range([mg_get_plot_bottom(args), args.top]); - return scale; -} - -function mg_define_y_scales (args) { - var scale = args.y_scale_type === 'log' ? d3.scale.log() : d3.scale.linear(); - if (args.y_scale_type === 'log') { - if (args.chart_type === 'histogram') { - // log histogram plots should start just below 1 - // so that bins with single counts are visible - args.processed.min_y = 0.2; - } else { - if (args.processed.min_y <= 0) { - args.processed.min_y = 1; - } - } - } - args.scales.Y = mg_y_domain_range(args, scale); - args.scales.Y.clamp(args.y_scale_type === 'log'); - - // used for ticks and such, and designed to be paired with log or linear - args.scales.Y_axis = mg_y_domain_range(args, d3.scale.linear()); -} - -function mg_add_y_label (g, args) { - if (args.y_label) { - g.append('text') - .attr('class', 'label') - .attr('x', function () { - return -1 * (mg_get_plot_top(args) + - ((mg_get_plot_bottom(args)) - (mg_get_plot_top(args))) / 2); - }) - .attr('y', function () { - return args.left / 2; - }) - .attr('dy', '0.4em') - .attr('text-anchor', 'middle') - .text(function (d) { - return args.y_label; - }) - .attr('transform', function (d) { - return 'rotate(-90)'; - }); - } -} - -function mg_process_scale_ticks (args) { - var scale_ticks = args.scales.Y.ticks(args.yax_count); - - function log10 (val) { - if (val === 1000) { - return 3; - } - if (val === 1000000) { - return 7; - } - return Math.log(val) / Math.LN10; - } - - if (args.y_scale_type === 'log') { - // get out only whole logs - scale_ticks = scale_ticks.filter(function (d) { - return Math.abs(log10(d)) % 1 < 1e-6 || Math.abs(log10(d)) % 1 > 1 - 1e-6; - }); - } - - // filter out fraction ticks if our data is ints and if ymax > number of generated ticks - var number_of_ticks = args.scales.Y.ticks(args.yax_count).length; - - // is our data object all ints? - var data_is_int = true; - args.data.forEach(function (d, i) { - d.forEach(function (d, i) { - if (d[args.y_accessor] % 1 !== 0) { - data_is_int = false; - return false; - } - }); - }); - - if (data_is_int && number_of_ticks > args.processed.max_y && args.format === 'count') { - // remove non-integer ticks - scale_ticks = scale_ticks.filter(function (d) { - return d % 1 === 0; - }); - } - args.processed.y_ticks = scale_ticks; -} - -function mg_add_y_axis_rim (g, args) { - var tick_length = args.processed.y_ticks.length; - if (!args.x_extended_ticks && !args.y_extended_ticks && tick_length) { - var y1scale, y2scale; - - if (args.axes_not_compact && args.chart_type !== 'bar') { - y1scale = args.height - args.bottom; - y2scale = args.top; - } else if (tick_length) { - y1scale = args.scales.Y(args.processed.y_ticks[0]).toFixed(2); - y2scale = args.scales.Y(args.processed.y_ticks[tick_length - 1]).toFixed(2); - } else { - y1scale = 0; - y2scale = 0; - } - - g.append('line') - .attr('x1', args.left) - .attr('x2', args.left) - .attr('y1', y1scale) - .attr('y2', y2scale); - } -} - -function mg_add_y_axis_tick_lines (g, args) { - g.selectAll('.mg-yax-ticks') - .data(args.processed.y_ticks).enter() - .append('line') - .classed('mg-extended-y-ticks', args.y_extended_ticks) - .attr('x1', args.left) - .attr('x2', function () { - return (args.y_extended_ticks) - ? args.width - args.right - : args.left - args.yax_tick_length; - }) - .attr('y1', function (d) { return args.scales.Y(d).toFixed(2); }) - .attr('y2', function (d) { return args.scales.Y(d).toFixed(2); }); -} - -function mg_add_y_axis_tick_labels (g, args) { - var yax_format = mg_compute_yax_format(args); - g.selectAll('.mg-yax-labels') - .data(args.processed.y_ticks).enter() - .append('text') - .attr('x', args.left - args.yax_tick_length * 3 / 2) - .attr('dx', -3) - .attr('y', function (d) { - return args.scales.Y(d).toFixed(2); - }) - .attr('dy', '.35em') - .attr('text-anchor', 'end') - .text(function (d) { - var o = yax_format(d); - return o; - }); -} - -function y_axis (args) { - if (!args.processed) { - args.processed = {}; - } - - var svg = mg_get_svg_child_of(args.target); - - set_min_max_y(args); - MG.call_hook('y_axis.process_min_max', args, args.processed.min_y, args.processed.max_y); - - mg_define_y_scales(args); - mg_add_scale_function(args, 'yf', 'Y', args.y_accessor); - - mg_selectAll_and_remove(svg, '.mg-y-axis'); - - if (!args.y_axis) { return this; } - - var g = mg_add_g(svg, 'mg-y-axis'); - mg_add_y_label(g, args); - mg_process_scale_ticks(args); - mg_add_y_axis_rim(g, args); - mg_add_y_axis_tick_lines(g, args); - mg_add_y_axis_tick_labels(g, args); - - if (args.y_rug) { y_rug(args); } - - return this; -} - -MG.y_axis = y_axis; - -function mg_add_categorical_labels (args) { - var svg = mg_get_svg_child_of(args.target); - mg_selectAll_and_remove(svg, '.mg-y-axis'); - var g = mg_add_g(svg, 'mg-y-axis'); - - var labels = g.selectAll('text').data(args.categorical_variables).enter().append('svg:text') - .attr('x', args.left) - .attr('y', function (d) { - return args.scales.Y(d) + args.scales.Y.rangeBand() / 2 + (args.buffer) * args.outer_padding_percentage; - }) - .attr('dy', '.35em') - .attr('text-anchor', 'end') - .text(String); - - mg_rotate_labels(labels, args.rotate_y_labels); -// if (args.rotate_y_labels) { -// labels.attr({ -// dy: 0, -// transform: function() { -// var elem = d3.select(this); -// return 'rotate('+args.rotate_y_labels+' '+elem.attr('x')+','+elem.attr('y')+')'; -// } -// }); -// } -} - -function y_axis_categorical (args) { - mg_add_categorical_scale(args, 'Y', args.categorical_variables, mg_get_plot_bottom(args), args.top, args.padding_percentage, args.outer_padding_percentage); - mg_add_scale_function(args, 'yf', 'Y', args.y_accessor); - if (!args.y_axis) { return this; } - mg_add_categorical_labels(args); - - return this; -} - -MG.y_axis_categorical = y_axis_categorical; - -function x_rug (args) { - 'use strict'; - args.rug_buffer_size = args.chart_type === 'point' - ? args.buffer / 2 - : args.buffer; - var rug = mg_make_rug(args, 'mg-x-rug'); - rug.attr('x1', args.scalefns.xf) - .attr('x2', args.scalefns.xf) - .attr('y1', args.height - args.bottom - args.rug_buffer_size) - .attr('y2', args.height - args.bottom); - mg_add_color_accessor_to_rug(rug, args, 'mg-x-rug-mono'); -} - -MG.x_rug = x_rug; - -function mg_add_processed_object (args) { - if (!args.processed) { - args.processed = {}; - } -} - -function mg_define_x_scale (args) { - mg_add_scale_function(args, 'xf', 'X', args.x_accessor); - mg_find_min_max_x(args); - - var time_scale = (args.utc_time) - ? d3.time.scale.utc() - : d3.time.scale(); - - args.scales.X = (args.time_series) - ? time_scale - : d3.scale.linear(); - - args.scales.X - .domain([args.processed.min_x, args.processed.max_x]) - .range([mg_get_plot_left(args), mg_get_plot_right(args) - args.additional_buffer]); -} - -function x_axis (args) { - 'use strict'; - - var svg = mg_get_svg_child_of(args.target); - mg_add_processed_object(args); - mg_define_x_scale(args); - - if (args.chart_type === 'point') { - mg_point_add_color_scale(args); - mg_point_add_size_scale(args); - } - mg_selectAll_and_remove(svg, '.mg-x-axis'); - - if (!args.x_axis) { return this; } - var g = mg_add_g(svg, 'mg-x-axis'); - - if (args.x_label) { mg_add_x_label(g, args); } - - mg_add_x_ticks(g, args); - mg_add_x_tick_labels(g, args); - - if (args.x_rug) { x_rug(args); } - - return this; -} - -MG.x_axis = x_axis; - -function x_axis_categorical (args) { - var svg = mg_get_svg_child_of(args.target); - var additional_buffer = 0; - - if (args.chart_type === 'bar') { additional_buffer = args.buffer + 5; } - - mg_add_categorical_scale(args, 'X', args.categorical_variables.reverse(), args.left, mg_get_plot_right(args) - additional_buffer); - mg_add_scale_function(args, 'xf', 'X', args.x_accessor); - mg_selectAll_and_remove(svg, '.mg-x-axis'); - - var g = mg_add_g(svg, 'mg-x-axis'); - - if (!args.x_axis) { return this; } - - mg_add_x_axis_categorical_labels(g, args, additional_buffer); - return this; -} - -function mg_add_x_axis_categorical_labels (g, args, additional_buffer) { - var labels = g.selectAll('text').data(args.categorical_variables).enter().append('svg:text'); - labels.attr('x', function (d) { - return args.scales.X(d) + args.scales.X.rangeBand() / 2 - + (args.buffer) * args.outer_padding_percentage + (additional_buffer / 2); - }) - .attr('y', mg_get_plot_bottom(args)) - .attr('dy', '.35em') - .attr('text-anchor', 'middle') - .text(String); - - if (args.truncate_x_labels) { - labels.each(function (d, idx) { - var elem = this, - width = args.scales.X.rangeBand(); - truncate_text(elem, d, width); - }); - } - mg_rotate_labels(labels, args.rotate_x_labels); -} - -MG.x_axis_categorical = x_axis_categorical; - -function mg_point_add_color_scale (args) { - var color_domain, color_range; - - if (args.color_accessor !== null) { - color_domain = mg_get_color_domain(args); - color_range = mg_get_color_range(args); - - if (args.color_type === 'number') { - args.scales.color = d3.scale.linear() - .domain(color_domain) - .range(color_range) - .clamp(true); - } else { - args.scales.color = args.color_range !== null - ? d3.scale.ordinal().range(color_range) - : (color_domain.length > 10 - ? d3.scale.category20() : d3.scale.category10()); - - args.scales.color.domain(color_domain); - } - mg_add_scale_function(args, 'color', 'color', args.color_accessor); - } -} - -function mg_get_color_domain (args) { - var color_domain; - if (args.color_domain === null) { - if (args.color_type === 'number') { - color_domain = d3.extent(args.data[0],function(d){return d[args.color_accessor];}); - } - else if (args.color_type === 'category') { - color_domain = d3.set(args.data[0] - .map(function (d) { return d[args.color_accessor]; })) - .values(); - - color_domain.sort(); - } - } else { - color_domain = args.color_domain; - } - return color_domain; -} - -function mg_get_color_range (args) { - var color_range; - if (args.color_range === null) { - if (args.color_type === 'number') { - color_range = ['blue', 'red']; - } else { - color_range = null; - } - } else { - color_range = args.color_range; - } - return color_range; -} - -function mg_point_add_size_scale (args) { - var min_size, max_size, size_domain, size_range; - if (args.size_accessor !== null) { - size_domain = mg_get_size_domain(args); - size_range = mg_get_size_range(args); - - args.scales.size = d3.scale.linear() - .domain(size_domain) - .range(size_range) - .clamp(true); - - mg_add_scale_function(args, 'size', 'size', args.size_accessor); - } -} - -function mg_get_size_domain (args) { - return args.size_domain === null ? - d3.extent(args.data[0], function(d) { return d[args.size_accessor]; }) : - args.size_domain; -} - -function mg_get_size_range (args) { - var size_range; - if (args.size_range === null) { - size_range = [1, 5]; // args.size_domain; - } else { - size_range = args.size_range; - } - return size_range; -} - -function mg_add_x_label (g, args) { - g.append('text') - .attr('class', 'label') - .attr('x', function () { - return (args.left + args.width - args.right) / 2; - }) - .attr('y', (args.height - args.bottom / 2).toFixed(2)) - .attr('dy', '.50em') - .attr('text-anchor', 'middle') - .text(function (d) { - return args.x_label; - }); -} - -function mg_default_bar_xax_format (args) { - return function (f) { - if (f < 1.0) { - // don't scale tiny values - return args.xax_units + d3.round(f, args.decimals); - } else { - var pf = d3.formatPrefix(f); - return args.xax_units + pf.scale(f) + pf.symbol; - } - }; -} - -function mg_get_time_frame (diff) { - // diff should be (max_x - min_x) / 1000, in other words, the difference in seconds. - var time_frame; - if (mg_milisec_diff(diff)) { - time_frame = 'millis'; - } else if ( mg_sec_diff(diff)) { - time_frame = 'seconds'; - } else if (mg_day_diff(diff)) { - time_frame = 'less-than-a-day'; - } else if (mg_four_days(diff)) { - time_frame = 'four-days'; - } else if (mg_many_days(diff)) { /// a handful of months? - time_frame = 'many-days'; - } else if (mg_many_months(diff)) { - time_frame = 'many-months'; - } else if (mg_years(diff)) { - time_frame = 'years'; - }else { - time_frame = 'default'; - } - return time_frame; -} - -function mg_milisec_diff (diff) { return diff < 10; } -function mg_sec_diff (diff) { return diff < 60; } -function mg_day_diff (diff) { return diff / (60 * 60) <= 24; } -function mg_four_days (diff) { return diff / (60 * 60) <= 24 * 4; } -function mg_many_days (diff) { return diff / (60 * 60 * 24) <= 93; } -function mg_many_months (diff) { return diff / (60*60*24) < 365*2; } -function mg_years (diff) { return diff / (60*60*24) >= 365*2; } - -function mg_get_time_format (utc, diff) { - var main_time_format; - if ( mg_milisec_diff(diff) ) { - main_time_format = MG.time_format(utc, '%M:%S.%L'); - } else if ( mg_sec_diff(diff) ) { - main_time_format = MG.time_format(utc, '%M:%S'); - - } else if ( mg_day_diff(diff) ) { - main_time_format = MG.time_format(utc, '%H:%M'); - - } else if ( mg_four_days(diff) ) { - main_time_format = MG.time_format(utc, '%H:%M'); - - } else if ( mg_many_days(diff) ) { - main_time_format = MG.time_format(utc, '%b %d'); - - } else if ( mg_many_months(diff) ) { - main_time_format = MG.time_format(utc, '%b'); - } else { - main_time_format = MG.time_format(utc, '%Y'); - - } - return main_time_format; -} - -function mg_process_time_format (args) { - var diff; - var main_time_format; - var time_frame; - - if (args.time_series) { - diff = (args.processed.max_x - args.processed.min_x) / 1000; - time_frame = mg_get_time_frame(diff); - main_time_format = mg_get_time_format(args.utc_time, diff); - } - - args.processed.main_x_time_format = main_time_format; - args.processed.x_time_frame = time_frame; -} - -function mg_default_xax_format (args) { - if (args.xax_format) { - return args.xax_format; - } - var data = args.processed.original_data || args.data; - var test_point = mg_flatten_array(data)[0][args.processed.original_x_accessor || args.x_accessor]; - return function (d) { - mg_process_time_format(args); - var pf = d3.formatPrefix(d); - if (test_point instanceof Date) { - return args.processed.main_x_time_format(new Date(d)); - } else if (typeof test_point === 'number') { - if (d < 1.0) { - // don't scale tiny values - return args.xax_units + d3.round(d, args.decimals); - } else { - pf = d3.formatPrefix(d); - return args.xax_units + pf.scale(d) + pf.symbol; - } - } else { - return d; - } - }; -} - -function mg_add_x_ticks (g, args) { - if (args.chart_type !== 'bar' && !args.y_extended_ticks) { - mg_add_x_axis_rim(args, g); - mg_add_x_axis_tick_lines(args, g); - } - -} - -function mg_add_x_axis_rim (args, g) { - var last_i = args.scales.X.ticks(args.xax_count).length - 1; - if (!args.x_extended_ticks) { - g.append('line') - .attr('x1', function () { - if (args.xax_count === 0) { - return mg_get_plot_left(args); - } else if (args.axes_not_compact && args.chart_type !== 'bar') { - return args.left; - } else { - return (args.scales.X(args.scales.X.ticks(args.xax_count)[0])).toFixed(2); - } - }) - .attr('x2', function () { - if (args.xax_count === 0 || (args.axes_not_compact && args.chart_type !== 'bar')) { - return mg_get_plot_right(args); - } else { - return args.scales.X(args.scales.X.ticks(args.xax_count)[last_i]).toFixed(2); - } - }) - .attr('y1', args.height - args.bottom) - .attr('y2', args.height - args.bottom); - } -} - -function mg_add_x_axis_tick_lines (args, g) { - var ticks = args.scales.X.ticks(args.xax_count); - g.selectAll('.mg-xax-ticks') - .data(ticks).enter() - .append('line') - .attr('x1', function (d) { return args.scales.X(d).toFixed(2); }) - .attr('x2', function (d) { return args.scales.X(d).toFixed(2); }) - .attr('y1', args.height - args.bottom) - .attr('y2', function () { - return (args.x_extended_ticks) - ? args.top - : args.height - args.bottom + args.xax_tick_length; - }) - .attr('class', function () { - if (args.x_extended_ticks) { - return 'mg-extended-x-ticks'; - } - }) - .classed('mg-xax-ticks', true); -} - -function mg_add_x_tick_labels (g, args) { - mg_add_primary_x_axis_label(args, g); - mg_add_secondary_x_axis_label(args, g); - -} - -function mg_add_primary_x_axis_label (args, g) { - var ticks = args.scales.X.ticks(args.xax_count); - var labels = g.selectAll('.mg-xax-labels') - .data(ticks).enter() - .append('text') - .attr('x', function (d) { return args.scales.X(d).toFixed(2); }) - .attr('y', (args.height - args.bottom + args.xax_tick_length * 7 / 3).toFixed(2)) - .attr('dy', '.50em') - .attr('text-anchor', 'middle'); - - if (args.time_series && args.european_clock) { - labels.append('tspan').classed('mg-european-hours', true).text(function (_d, i) { - var d = new Date(_d); - if (i === 0) return d3.time.format('%H')(d); - else return ''; - }); - labels.append('tspan').classed('mg-european-minutes-seconds', true).text(function (_d, i) { - var d = new Date(_d); - return ':' + args.processed.xax_format(d); - }); - } else { - labels.text(function (d) { - return args.xax_units + args.processed.xax_format(d); - }); - } - // CHECK TO SEE IF OVERLAP for labels. If so, - // remove half of them. This is a dirty hack. - // We will need to figure out a more principled way of doing this. - if (mg_elements_are_overlapping(labels)) { - labels.filter(function(d,i) { - return (i+1) % 2 === 0; - }).remove(); - - var svg = mg_get_svg_child_of(args.target); - svg.selectAll('.mg-xax-ticks').filter(function(d,i){ return (i+1) % 2 === 0; }) - .remove(); - } -} - -function mg_add_secondary_x_axis_label (args, g) { - if (args.time_series && (args.show_years || args.show_secondary_x_label)) { - var tf = mg_get_yformat_and_secondary_time_function(args); - mg_add_secondary_x_axis_elements(args, g, tf.timeframe, tf.yformat, tf.secondary); - } -} - -function mg_get_yformat_and_secondary_time_function (args) { - var tf = {}; - tf.timeframe = args.processed.x_time_frame; - switch (tf.timeframe) { - case 'millis': - case 'seconds': - tf.secondary = d3.time.days; - if (args.european_clock) tf.yformat = MG.time_format(args.utc_time, '%b %d'); - else tf.yformat = MG.time_format(args.utc_time, '%I %p'); - break; - case 'less-than-a-day': - tf.secondary = d3.time.days; - tf.yformat = MG.time_format(args.utc_time, '%b %d'); - break; - case 'four-days': - tf.secondary = d3.time.days; - tf.yformat = MG.time_format(args.utc_time, '%b %d'); - break; - case 'many-days': - tf.secondary = d3.time.years; - tf.yformat = MG.time_format(args.utc_time, '%Y'); - break; - case 'many-months': - tf.secondary = d3.time.years; - tf.yformat = MG.time_format(args.utc_time, '%b'); - break; - default: - tf.secondary = d3.time.years; - tf.yformat = MG.time_format(args.utc_time, '%Y'); - } - return tf; -} - -function mg_add_secondary_x_axis_elements (args, g, time_frame, yformat, secondary_function) { - var years = secondary_function(args.processed.min_x, args.processed.max_x); - if (years.length === 0) { - var first_tick = args.scales.X.ticks(args.xax_count)[0]; - years = [first_tick]; - } - - var yg = mg_add_g(g, 'mg-year-marker'); - if (time_frame === 'default' && args.show_year_markers) { - mg_add_year_marker_line(args, yg, years, yformat); - } - if (time_frame != 'years') mg_add_year_marker_text(args, yg, years, yformat); -} - -function mg_add_year_marker_line (args, g, years, yformat) { - g.selectAll('.mg-year-marker') - .data(years).enter() - .append('line') - .attr('x1', function (d) { return args.scales.X(d).toFixed(2); }) - .attr('x2', function (d) { return args.scales.X(d).toFixed(2); }) - .attr('y1', mg_get_top(args)) - .attr('y2', mg_get_bottom(args)); -} - -function mg_add_year_marker_text (args, g, years, yformat) { - g.selectAll('.mg-year-marker') - .data(years).enter() - .append('text') - .attr('x', function (d, i) { - return args.scales.X(d).toFixed(2); - }) - .attr('y', function () { - var xAxisTextElement = d3.select(args.target) - .select('.mg-x-axis text').node().getBoundingClientRect(); - return (mg_get_bottom(args) + args.xax_tick_length * 7 / 3) + (xAxisTextElement.height * 0.8); - }) - .attr('dy', '.50em') - .attr('text-anchor', 'middle') - .text(function (d) { - return yformat(new Date(d)); - }); -} - -function mg_min_max_x_for_nonbars (mx, args, data) { - var extent_x = d3.extent(data, function (d) { return d[args.x_accessor]; }); - mx.min = extent_x[0]; - mx.max = extent_x[1]; -} - -function mg_min_max_x_for_bars (mx, args, data) { - mx.min = 0; - mx.max = d3.max(data, function (d) { - var trio = [ - d[args.x_accessor], - (d[args.baseline_accessor]) ? d[args.baseline_accessor] : 0, - (d[args.predictor_accessor]) ? d[args.predictor_accessor] : 0 - ]; - return Math.max.apply(null, trio); - }); -} - -function mg_min_max_x_for_dates (mx) { - var yesterday = MG.clone(mx.min).setDate(mx.min.getDate() - 1); - var tomorrow = MG.clone(mx.min).setDate(mx.min.getDate() + 1); - mx.min = yesterday; - mx.max = tomorrow; -} - -function mg_min_max_x_for_numbers (mx) { - // this seems silly. I envision a problem with something this simplistic. - mx.min = mx.min - 1; - mx.max = mx.max + 1; -} - -function mg_min_max_x_for_strings (mx) { - // ok. Not sure who wrote this, but this seems also pretty silly. We - // should not be allowing strings here to be coerced into numbers. Veto. - mx.min = Number(mx.min) - 1; - mx.max = Number(mx.max) + 1; -} - -function mg_force_xax_count_to_be_two (args) { - args.xax_count = 2; -} - -function mg_sort_through_data_type_and_set_x_min_max_accordingly (mx, args, data) { - if (args.chart_type === 'line' || args.chart_type === 'point' || args.chart_type === 'histogram') { - mg_min_max_x_for_nonbars(mx, args, data); - - } else if (args.chart_type === 'bar') { - mg_min_max_x_for_bars(mx, args, data); - } - // if data set is of length 1, expand the range so that we can build the x-axis - if (mx.min === mx.max && !(args.min_x && args.max_x)) { - if (mx.min instanceof Date) { - mg_min_max_x_for_dates(mx); - } else if (typeof min_x === 'number') { - mg_min_max_x_for_numbers(mx); - } else if (typeof min_x === 'string') { - mg_min_max_x_for_strings(mx); - } - // force xax_count to be 2 - mg_force_xax_count_to_be_two(args); - } -} - -function mg_find_min_max_x_from_data (args) { - var all_data = mg_flatten_array(args.data); - var mx = {}; - mg_sort_through_data_type_and_set_x_min_max_accordingly(mx, args, all_data); - mx.min = args.min_x || mx.min; - mx.max = args.max_x || mx.max; - args.x_axis_negative = false; - args.processed.min_x = mx.min; - args.processed.max_x = mx.max; -} - -function mg_find_min_max_x (args) { - mg_find_min_max_x_from_data(args); - mg_select_xax_format(args); - MG.call_hook('x_axis.process_min_max', args, args.processed.min_x, args.processed.max_x); - if (!args.time_series) { - if (args.processed.min_x < 0) { - args.processed.min_x = args.processed.min_x - (args.processed.max_x * (args.inflator - 1)); - args.x_axis_negative = true; - } - } - - if (args.chart_type === 'bar') { - args.additional_buffer = args.buffer * 5; - } else { - args.additional_buffer = 0; - } -} - -function mg_select_xax_format (args) { - var c = args.chart_type; - - if (!args.processed.xax_format) { - if (args.xax_format) { - args.processed.xax_format = args.xax_format; - } else { - if (c === 'line' || c === 'point' || c === 'histogram') { - args.processed.xax_format = mg_default_xax_format(args); - } else if (c === 'bar') { - args.processed.xax_format = mg_default_bar_xax_format(args); - } - } - } -} - -function mg_merge_args_with_defaults (args) { - var defaults = { - target: null, - title: null, - description: null - }; - if (!args) { args = {}; } - - if (!args.processed) { - args.processed = {}; - } - - args = merge_with_defaults(args, defaults); - return args; -} - -function mg_is_time_series (args) { - var first_elem = mg_flatten_array(args.processed.original_data || args.data)[0]; - args.time_series = first_elem[args.processed.original_x_accessor || args.x_accessor] instanceof Date; -} - -function mg_init_compute_width (args) { - var svg_width = args.width; - // are we setting the aspect ratio? - if (args.full_width) { - // get parent element - svg_width = get_width(args.target); - } - args.width = svg_width; -} - -function mg_init_compute_height (args) { - var svg_height = args.height; - if (args.full_height) { - svg_height = get_height(args.target); - } - - if (args.chart_type === 'bar' && svg_height === null) { - svg_height = args.height = args.data[0].length * args.bar_height + args.top + args.bottom; - } - - args.height = svg_height; -} - -function mg_remove_svg_if_chart_type_has_changed (svg, args) { - if ((!svg.selectAll('.mg-main-line').empty() && args.chart_type !== 'line') || - (!svg.selectAll('.mg-points').empty() && args.chart_type !== 'point') || - (!svg.selectAll('.mg-histogram').empty() && args.chart_type !== 'histogram') || - (!svg.selectAll('.mg-barplot').empty() && args.chart_type !== 'bar') - ) { - svg.remove(); - } -} - -function mg_add_svg_if_it_doesnt_exist (svg, args) { - if (mg_get_svg_child_of(args.target).empty()) { - svg = d3.select(args.target) - .append('svg') - .classed('linked', args.linked) - .attr('width', args.width) - .attr('height', args.height); - } - return svg; -} - -function mg_add_clip_path_for_plot_area (svg, args) { - svg.selectAll('.mg-clip-path').remove(); - svg.append('defs') - .attr('class', 'mg-clip-path') - .append('clipPath') - .attr('id', 'mg-plot-window-' + mg_target_ref(args.target)) - .append('svg:rect') - .attr('x', args.left) - .attr('y', args.top) - .attr('width', args.width - args.left - args.right - args.buffer) - .attr('height', args.height - args.top - args.bottom - args.buffer + 1); -} - -function mg_adjust_width_and_height_if_changed (svg, args) { - if (args.width !== Number(svg.attr('width'))) { - svg.attr('width', args.width); - } - if (args.height !== Number(svg.attr('height'))) { - svg.attr('height', args.height); - } -} - -function mg_set_viewbox_for_scaling (svg, args) { - // we need to reconsider how we handle automatic scaling - svg.attr('viewBox', '0 0 ' + args.width + ' ' + args.height); - if (args.full_width || args.full_height) { - svg.attr('preserveAspectRatio', 'xMinYMin meet'); - } -} - -function mg_remove_missing_classes_and_text (svg) { - // remove missing class - svg.classed('mg-missing', false); - - // remove missing text - svg.selectAll('.mg-missing-text').remove(); - svg.selectAll('.mg-missing-pane').remove(); -} - -function mg_remove_outdated_lines (svg, args) { - // if we're updating an existing chart and we have fewer lines than - // before, remove the outdated lines, e.g. if we had 3 lines, and we're calling - // data_graphic() on the same target with 2 lines, remove the 3rd line - - var i = 0; - if (svg.selectAll('.mg-main-line')[0].length >= args.data.length) { - // now, the thing is we can't just remove, say, line3 if we have a custom - // line-color map, instead, see which are the lines to be removed, and delete those - if (args.custom_line_color_map.length > 0) { - var array_full_series = function (len) { - var arr = new Array(len); - for (var i = 0; i < arr.length; i++) { arr[i] = i + 1; } - return arr; - }; - - // get an array of lines ids to remove - var lines_to_remove = arr_diff( - array_full_series(args.max_data_size), - args.custom_line_color_map); - - for (i = 0; i < lines_to_remove.length; i++) { - svg.selectAll('.mg-main-line.mg-line' + lines_to_remove[i] + '-color') - .remove(); - } - } else { - // if we don't have a custom line-color map, just remove the lines from the end - - var num_of_new = args.data.length; - var num_of_existing = svg.selectAll('.mg-main-line')[0].length; - - for (i = num_of_existing; i > num_of_new; i--) { - svg.selectAll('.mg-main-line.mg-line' + i + '-color') - .remove(); - } - } - } -} - -function mg_raise_container_error(container, args){ - if (container.empty()) { - console.warn('The specified target element "' + args.target + '" could not be found in the page. The chart will not be rendered.'); - return; - } -} - -function init (args) { - 'use strict'; - args = arguments[0]; - args = mg_merge_args_with_defaults(args); - // If you pass in a dom element for args.target, the expectation - // of a string elsewhere will break. - var container = d3.select(args.target); - mg_raise_container_error(container, args); - - var svg = container.selectAll('svg'); - - mg_is_time_series(args); - mg_init_compute_width(args); - mg_init_compute_height(args); - - mg_remove_svg_if_chart_type_has_changed(svg, args); - svg = mg_add_svg_if_it_doesnt_exist(svg, args); - - mg_add_clip_path_for_plot_area(svg, args); - mg_adjust_width_and_height_if_changed(svg, args); - mg_set_viewbox_for_scaling(svg, args); - mg_remove_missing_classes_and_text(svg); - chart_title(args); - mg_remove_outdated_lines(svg, args); - - return this; -} - -MG.init = init; - -function mg_return_label (d) { - return d.label; -} - -function mg_remove_existing_markers (svg) { - svg.selectAll('.mg-markers').remove(); - svg.selectAll('.mg-baselines').remove(); -} - -function mg_in_range (args) { - return function (d) { - return (args.scales.X(d[args.x_accessor]) > mg_get_plot_left(args)) - && (args.scales.X(d[args.x_accessor]) < mg_get_plot_right(args)); - }; -} - -function mg_x_position (args) { - return function (d) { - return args.scales.X(d[args.x_accessor]); - }; -} - -function mg_x_position_fixed (args) { - var _mg_x_pos = mg_x_position(args); - return function (d) { - return _mg_x_pos(d).toFixed(2); - }; -} - -function mg_y_position_fixed (args) { - var _mg_y_pos = args.scales.Y; - return function (d) { - return _mg_y_pos(d.value).toFixed(2); - }; -} - -function mg_place_annotations(checker, class_name, args, svg, line_fcn, text_fcn){ - var g; - if (checker) { - g = svg.append('g').attr('class', class_name); - line_fcn(g, args); - text_fcn(g, args); - } -} - -function mg_place_markers (args, svg) { - mg_place_annotations(args.markers, 'mg-markers', args, svg, mg_place_marker_lines, mg_place_marker_text); -} - -function mg_place_baselines (args, svg) { - mg_place_annotations(args.baselines, 'mg-baselines', args, svg, mg_place_baseline_lines, mg_place_baseline_text); -} - -function mg_place_marker_lines (gm, args) { - var x_pos_fixed = mg_x_position_fixed(args); - gm.selectAll('.mg-markers') - .data(args.markers.filter(mg_in_range(args))) - .enter() - .append('line') - .attr('x1', x_pos_fixed) - .attr('x2', x_pos_fixed) - .attr('y1', args.top) - .attr('y2', mg_get_plot_bottom(args)) - .attr('class', function (d) { - return d.lineclass; - }) - .attr('stroke-dasharray', '3,1'); -} - -function mg_place_marker_text (gm, args) { - gm.selectAll('.mg-markers') - .data(args.markers.filter(mg_in_range(args))) - .enter() - .append('text') - .attr('class', function (d) { return d.textclass || ''; }) - .classed('mg-marker-text', true) - .attr('x', mg_x_position(args)) - .attr('y', args.top * 0.95) - .attr('text-anchor', 'middle') - .text(mg_return_label) - .each(function (d) { - if (d.click) d3.select(this).style('cursor', 'pointer').on('click', d.click); - }); - mg_prevent_horizontal_overlap(gm.selectAll('.mg-marker-text')[0], args); -} - -function mg_place_baseline_lines (gb, args) { - var y_pos = mg_y_position_fixed(args); - gb.selectAll('.mg-baselines') - .data(args.baselines) - .enter().append('line') - .attr('x1', mg_get_plot_left(args)) - .attr('x2', mg_get_plot_right(args)) - .attr('y1', y_pos) - .attr('y2', y_pos); -} - -function mg_place_baseline_text (gb, args) { - var y_pos = mg_y_position_fixed(args); - gb.selectAll('.mg-baselines') - .data(args.baselines) - .enter().append('text') - .attr('x', mg_get_plot_right(args)) - .attr('y', y_pos) - .attr('dy', -3) - .attr('text-anchor', 'end') - .text(mg_return_label); -} - -function markers (args) { - 'use strict'; - var svg = mg_get_svg_child_of(args.target); - mg_remove_existing_markers(svg); - mg_place_markers(args, svg); - mg_place_baselines(args, svg); - return this; -} - -MG.markers = markers; - -function mouseover_tspan (svg, text) { - var tspan = ''; - var cl = null; - if (arguments.length === 3) cl = arguments[2]; - tspan = svg.append('tspan').text(text); - if (cl !== null) tspan.classed(cl, true); - - return (function () { - this.tspan = tspan; - - this.bold = function () { - this.tspan.attr('font-weight', 'bold'); - return this; - }; - this.color = function (args, d) { - if (args.chart_type === 'line') { - this.tspan.classed('mg-hover-line' + d.line_id + '-color', args.colors === null) - .attr('stroke', args.colors === null ? '' : args.colors[d.line_id - 1]); - } else if (args.chart_type === 'point') { - if (args.color_accessor !== null) { - this.tspan.attr('fill', args.scalefns.color(d)); - this.tspan.attr('stroke', args.scalefns.color(d)); - } else { - this.tspan.classed('mg-points-mono', true); - } - } - }; - this.x = function (x) { - this.tspan.attr('x', x); - return this; - }; - this.y = function (y) { - this.tspan.attr('y', y); - return this; - }; - this.elem = function () { - return this.tspan; - }; - return this; - })(); -} - -function mg_reset_active_datapoint_text (svg) { - var textContainer = svg.select('.mg-active-datapoint'); - textContainer - .selectAll('*') - .remove(); - return textContainer; -} - -function mg_format_aggregate_rollover_text (args, svg, textContainer, formatted_x, formatted_y, num, fmt, d, i) { - var lineCount = 0; - var lineHeight = 1.1; - if (args.time_series) { - mg_append_aggregate_rollover_timeseries(args, textContainer, formatted_x, d, num); - } else { - mg_append_aggregate_rollover_text(args, textContainer, formatted_x, d, num); - } - - // append an blank ( ) line to mdash positioning - mouseover_tspan(textContainer, '\u00A0').x(0).y((lineCount * lineHeight) + 'em'); -} - -function mg_append_aggregate_rollover_timeseries (args, textContainer, formatted_x, d, num) { - var lineCount = 0; - var lineHeight = 1.1; - var formatted_y; - - mouseover_tspan(textContainer, formatted_x.trim()); - - lineCount = 1; - var sub_container; - d.values.forEach(function (datum) { - sub_container = textContainer.append('tspan').attr('x', 0).attr('y', (lineCount * lineHeight) + 'em'); - formatted_y = mg_format_y_rollover(args, num, datum); - mouseover_tspan(sub_container, '\u2014 ') - .color(args, datum); - mouseover_tspan(sub_container, formatted_y); - - lineCount++; - }); - // necessary blank line. - mouseover_tspan(textContainer, '\u00A0').x(0).y((lineCount * lineHeight) + 'em'); -} - -function mg_append_aggregate_rollover_text (args, textContainer, formatted_x, d, num) { - var lineCount = 0; - var lineHeight = 1.1; - d.values.forEach(function (datum) { - formatted_y = mg_format_y_rollover(args, num, datum); - - if (args.y_rollover_format !== null) { - formatted_y = number_rollover_format(args.y_rollover_format, datum, args.y_accessor); - } else { - formatted_y = args.yax_units + num(datum[args.y_accessor]); - } - - sub_container = textContainer.append('tspan').attr('x', 0).attr('y', (lineCount * lineHeight) + 'em'); - formatted_y = mg_format_y_rollover(args, num, datum); - mouseover_tspan(sub_container, '\u2014 ') - .color(args, datum); - mouseover_tspan(sub_container, formatted_x + ' ' + formatted_y); - - lineCount++; - }); -} - -function mg_update_rollover_text (args, svg, fmt, shape, d, i) { - var num = format_rollover_number(args); - var textContainer = mg_reset_active_datapoint_text(svg); - var formatted_y = mg_format_y_rollover(args, num, d); - var formatted_x = mg_format_x_rollover(args, fmt, d); - - // rollover text when aggregate_rollover is enabled - if (args.aggregate_rollover && args.data.length > 1) { - mg_format_aggregate_rollover_text(args, svg, textContainer, formatted_x, formatted_y, num, fmt, d, i); - - } else { - // rollover text when aggregate_rollover is not enabled - if (args.time_series) textContainer.select('*').remove(); - - // label. - if (args.legend || args.label_accessor) { - mouseover_tspan(textContainer, - args.chart_type === 'line' ? args.legend[d.line_id - 1] + ' ' : d[args.label_accessor] + ' ') - .color(args, d); - } - - // shape to accompany rollover. - if (args.data.length > 1 || args.chart_type === 'point') { - mouseover_tspan(textContainer, shape + ' ').color(args, d); - } - // rollover text. - mouseover_tspan(textContainer, formatted_x, args.time_series ? 'mg-x-rollover-text' : null); - mouseover_tspan(textContainer, formatted_y, args.time_series ? 'mg-y-rollover-text' : null); - } -} - -function mg_window_listeners(args) { - mg_if_aspect_ratio_resize_svg(args); -} - -function mg_if_aspect_ratio_resize_svg(args) { - // have we asked the svg to fill a div, if so resize with div - if (args.full_width || args.full_height) { - if (window.onresize === null) { - window.onresize = window_listener; - } - } - - function window_listener() { - var svg = d3.select(args.target).select('svg'); - - var aspect = svg.attr('width') !== 0 - ? (svg.attr('height') / svg.attr('width')) - : 0; - - var newWidth = get_width(args.target); - - svg.attr('width', newWidth); - svg.attr('height', aspect * newWidth); - } -} - -if (typeof jQuery !== 'undefined') { - /*! - * Bootstrap v3.3.1 (http://getbootstrap.com) - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - - /*! - * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=c3834cc5b59ef727da53) - * Config saved to config.json and https://gist.github.com/c3834cc5b59ef727da53 - */ - - /* ======================================================================== - * Bootstrap: dropdown.js v3.3.1 - * http://getbootstrap.com/javascript/#dropdowns - * ======================================================================== - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - - +function ($) { - 'use strict'; - - if(typeof $().dropdown == 'function') - return true; - - // DROPDOWN CLASS DEFINITION - // ========================= - - var backdrop = '.dropdown-backdrop'; - var toggle = '[data-toggle="dropdown"]'; - var Dropdown = function (element) { - $(element).on('click.bs.dropdown', this.toggle); - }; - - Dropdown.VERSION = '3.3.1'; - - Dropdown.prototype.toggle = function (e) { - var $this = $(this); - - if ($this.is('.disabled, :disabled')) return; - - var $parent = getParent($this); - var isActive = $parent.hasClass('open'); - - clearMenus(); - - if (!isActive) { - if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { - // if mobile we use a backdrop because click events don't delegate - $(' - -
    - -
    -

    {{t "/performance/discrete/sub_heading/1" credentials}} {{t "/performance/discrete/sub_heading/2" credentials}}

    -
    - {{t "/performance/discrete/subtitle" credentials}} - -
    -
    -
    -
    {{t "/performance/discrete/panchayat_chart_placeholder" credentials}}
    -
    -
    -
    {{t "/total_trans" credentials}}
    -
    -
    - - - diff --git a/app/templates/performance/overview.hbs b/app/templates/performance/overview.hbs deleted file mode 100644 index 70555833..00000000 --- a/app/templates/performance/overview.hbs +++ /dev/null @@ -1,56 +0,0 @@ -
    - {{> loader}} -
    - - {{!-- Overview --}} -
    -
    -

    {{t "/performance/overview/chart_a/title" credentials}}

    -

    - {{t "/performance/overview/chart_a/description" credentials}} - -

    - -
    -
    {{t "/total_trans" credentials}}
    -
    -
    -
    -
    -
    - {{!-- Performance Comparison --}} -
    -
    -
    -

    {{t "/performance/overview/chart_b/title" credentials}}

    -

    - {{t "/performance/overview/chart_b/description" credentials}} - -

    - -
    -
    -
    {{t "/total_trans" credentials}}
    -
    -
    -
    -
    -
    - {{> footer}} -
    -
    diff --git a/app/templates/performance/performance.hbs b/app/templates/performance/performance.hbs new file mode 100644 index 00000000..e69de29b diff --git a/lib/jobs.js b/lib/jobs.js deleted file mode 100644 index 2dbddee0..00000000 --- a/lib/jobs.js +++ /dev/null @@ -1,58 +0,0 @@ -'use strict'; - -var path = require('path'); -var readline = require('readline'); -var glob = require('glob'); -var fs = require('fs'); - - -var today = new Date(); -var logDate = today.getFullYear() + '-' + ('0' + (today.getMonth() + 1)).slice(-2) + '-' + today.getDate(); -var logFilePattern = 'logs/ops/payops-' + logDate + '-*.log'; - -var stats = { - date: logDate, - // date: '2016-01-10', - cpu: null, - mem_total: null, - mem_used: null, - uptime: null, - heap_total: null, - heap_used: null, - sample_count: 0 -}; - -glob(logFilePattern, function(er, files) { - var counter = 0; - files.forEach(function(file) { - var lineReader = readline.createInterface({ - input: fs.createReadStream(file) - }); - lineReader.on('line', function(line) { - var ops = JSON.parse(line); - if (!stats.cpu) { - stats.cpu = ops.os.load[2]; - stats.mem_total = ops.os.mem.total; - stats.mem_used = ops.proc.mem.rss; - stats.heap_total = ops.proc.mem.heapTotal; - stats.heap_used = ops.proc.mem.heapUsed; - stats.uptime = ops.proc.uptime; - stats.sample_count = stats.sample_count + 1; - } else { - stats.cpu = (stats.cpu + ops.os.load[2]) / 2; - stats.mem_used = (stats.mem_used + ops.proc.mem.rss) / 2; - stats.heap_used = (stats.heap_used + ops.proc.mem.heapUsed) / 2; - stats.uptime = ops.proc.uptime; - stats.sample_count = stats.sample_count + 1; - } - }); - lineReader.on('close', function() { - counter++; - if (counter === files.length) { - fs.appendFile(path.resolve(__dirname) + '/../logs/stats/stats.log', JSON.stringify(stats) + '\n', function(err) { - console.log('Done'); - }); - } - }); - }); -}); From f94c405b80f2abb92cf31382608b6df5e6499193 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 5 Aug 2016 15:07:58 +0530 Subject: [PATCH 045/314] Cleanup plugins --- tasks/webpack.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tasks/webpack.js b/tasks/webpack.js index b71f84e9..4729c53b 100644 --- a/tasks/webpack.js +++ b/tasks/webpack.js @@ -15,8 +15,7 @@ Gulp.task('webpack', function() { var config = { entry: { vendor: ['jquery', 'd3'], - app: './assets/scripts/index.js', - mdash: './assets/scripts/monitor.js' + app: './assets/scripts/index.js' }, watch: true, cache: true, @@ -39,12 +38,6 @@ Gulp.task('webpack', function() { warnings: false } }), - new ProvidePlugin({ - $: 'jquery', - jQuery: 'jquery', - 'window.jQuery': 'jquery', - 'root.jQuery': 'jquery' - }), new CommonsChunkPlugin({ name: 'vendor', filename: 'vendor.js', From 423b0a549e186b13e9dfff254bab4a8ba36ccea1 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 5 Aug 2016 17:00:48 +0530 Subject: [PATCH 046/314] Cleanup gulp tasks --- package.json | 7 +++---- tasks/assets.js | 18 +++++++++--------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index e2febf4b..09add047 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,8 @@ "glue": "^3.3.0", "good": "^7.0.1", "good-file": "^6.0.1", - "googleapis": "^11.0.0", "handlebars": "^4.0.5", - "hapi": "^13.5.0", + "hapi": "^14.1.0", "hapi-auth-cookie": "^6.1.1", "hapi-context-credentials": "^2.0.0", "hoek": "^4.0.1", @@ -66,7 +65,7 @@ "babel-preset-react": "^6.11.1", "code": "^3.0.1", "del": "^2.2.1", - "eslint-plugin-react": "^5.2.2", + "eslint-plugin-react": "^6.0.0", "gulp": "^3.9.1", "gulp-autoprefixer": "^3.1.0", "gulp-eslint": "^3.0.1", @@ -74,7 +73,7 @@ "gulp-nodemon": "^2.1.0", "gulp-rev-all": "^0.8.24", "gulp-sass": "^2.3.2", - "gulp-uglify": "^1.5.4", + "gulp-uglify": "^2.0.0", "gulp-util": "^3.0.7", "lab": "^10.9.0", "react": "^15.2.1", diff --git a/tasks/assets.js b/tasks/assets.js index a4b212db..fd45c964 100644 --- a/tasks/assets.js +++ b/tasks/assets.js @@ -1,14 +1,14 @@ 'use strict'; -var Gulp = require('gulp'); -var Sass = require('gulp-sass'); -var paths = require('../config/assets'); -var autoprefixer = require('gulp-autoprefixer'); +const Gulp = require('gulp'); +const Sass = require('gulp-sass'); +const Paths = require('../config/assets'); +const Autoprefixer = require('gulp-autoprefixer'); Gulp.task('styles', function() { Gulp.src('./assets/styles/index.scss') .pipe(Sass().on('error', Sass.logError)) - .pipe(autoprefixer({ + .pipe(Autoprefixer({ browsers: ['last 2 versions'], cascade: false })) @@ -16,21 +16,21 @@ Gulp.task('styles', function() { }); Gulp.task('fonts', function() { - return Gulp.src(paths.get('/fonts')) + return Gulp.src(Paths.get('/fonts')) .pipe(Gulp.dest('.build/fonts')); }); Gulp.task('images', function() { - return Gulp.src(paths.get('/images')) + return Gulp.src(Paths.get('/images')) .pipe(Gulp.dest('.build/images')); }); Gulp.task('misc', function() { - return Gulp.src(paths.get('/misc')) + return Gulp.src(Paths.get('/misc')) .pipe(Gulp.dest('.build/misc')); }); Gulp.task('fonts', function() { - return Gulp.src(paths.get('/fonts')) + return Gulp.src(Paths.get('/fonts')) .pipe(Gulp.dest('.build/fonts')); }); From ebbd0f7a50e513d5071c026703d1fe70673e4507 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 5 Aug 2016 17:03:54 +0530 Subject: [PATCH 047/314] Update package --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 09add047..89065720 100644 --- a/package.json +++ b/package.json @@ -6,16 +6,16 @@ "main": "index.js", "scripts": { "test": "node node_modules/lab/bin/lab", - "start": "node server.js" + "start": "gulp" }, "repository": { "type": "git", "url": "git+https://github.com/hks-epod/paydash.git" }, "keywords": [ - "Hackers League", - "HapiJS", - "React" + "Paydash", + "Payment", + "MGNREGA" ], "author": "Ravi Suhag", "license": "MIT", From 6293a3ca121980a87277a80a1ad907812bf3efdf Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 5 Aug 2016 17:37:18 +0530 Subject: [PATCH 048/314] Add header style for light theme --- app/templates/layouts/default.hbs | 12 +- app/templates/partials/header.hbs | 43 +- assets/styles/base/base.scss | 24 + assets/styles/base/buttons.scss | 63 ++ assets/styles/base/forms.scss | 78 ++ assets/styles/base/grid.scss | 677 ++++++++++++++++++ assets/styles/base/lists.scss | 20 + assets/styles/base/spacing.scss | 27 + assets/styles/base/typography.scss | 43 ++ assets/styles/helpers/placeholders.scss | 7 + assets/styles/helpers/utils.scss | 32 + assets/styles/index.scss | 52 ++ assets/styles/layout/containers.scss | 18 + assets/styles/layout/metabar.scss | 82 +++ assets/styles/modules/dropdown.scss | 153 ++++ assets/styles/modules/menu.scss | 95 +++ assets/styles/modules/message.scss | 38 + assets/styles/modules/misc.scss | 4 + assets/styles/scales/base.scss | 34 + assets/styles/scales/color.scss | 38 + assets/styles/scales/type.scss | 52 ++ assets/styles/vendor/normalize.scss | 427 +++++++++++ assets/styles/vendor/stroke/helper.css | 191 +++++ .../styles/vendor/stroke/pe-icon-7-stroke.css | 632 ++++++++++++++++ 24 files changed, 2803 insertions(+), 39 deletions(-) create mode 100644 assets/styles/base/base.scss create mode 100644 assets/styles/base/buttons.scss create mode 100644 assets/styles/base/forms.scss create mode 100644 assets/styles/base/grid.scss create mode 100644 assets/styles/base/lists.scss create mode 100644 assets/styles/base/spacing.scss create mode 100644 assets/styles/base/typography.scss create mode 100644 assets/styles/helpers/placeholders.scss create mode 100644 assets/styles/helpers/utils.scss create mode 100644 assets/styles/layout/containers.scss create mode 100644 assets/styles/layout/metabar.scss create mode 100644 assets/styles/modules/dropdown.scss create mode 100644 assets/styles/modules/menu.scss create mode 100644 assets/styles/modules/message.scss create mode 100644 assets/styles/modules/misc.scss create mode 100644 assets/styles/scales/base.scss create mode 100644 assets/styles/scales/color.scss create mode 100644 assets/styles/scales/type.scss create mode 100644 assets/styles/vendor/normalize.scss create mode 100644 assets/styles/vendor/stroke/helper.css create mode 100755 assets/styles/vendor/stroke/pe-icon-7-stroke.css diff --git a/app/templates/layouts/default.hbs b/app/templates/layouts/default.hbs index 5d3b2885..3989cff5 100644 --- a/app/templates/layouts/default.hbs +++ b/app/templates/layouts/default.hbs @@ -2,17 +2,7 @@ - - {{#if title}}{{title}} - {{#if q}}{{q}}{{/if}}{{else}}PayDash{{/if}} - - {{#if package}} - - - - - - {{/if}} + PayDash diff --git a/app/templates/partials/header.hbs b/app/templates/partials/header.hbs index ae892335..a43d9936 100644 --- a/app/templates/partials/header.hbs +++ b/app/templates/partials/header.hbs @@ -1,41 +1,28 @@
    - Paydash - + + + {{#if credentials}}
    - - - - - ); diff --git a/assets/styles/views/musters.scss b/assets/styles/views/musters.scss index d5d32323..b635db85 100644 --- a/assets/styles/views/musters.scss +++ b/assets/styles/views/musters.scss @@ -18,19 +18,22 @@ padding: 20px; text-align: center } +.card-top{ + min-height: 100px; +} .card-head{ text-transform: uppercase; font-weight: 400; font-size: 1.2em; margin: 10px 0 0; - letter-spacing: .1em + letter-spacing: .1em; } .card-designation{ color: $color-grey-lighter; font-size: $fontSize-small; } .card-numbers{ - margin: 30px 0; + margin: 30px 0 40px; } .card-number-sub{ font-size: $fontSize-smaller; From 51c9b66bcfb022de02c27e1f0eeb3bcc5be8aa0e Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Wed, 17 Aug 2016 19:02:43 +0530 Subject: [PATCH 130/314] Implement modal --- assets/scripts/components/card.jsx | 53 +++++++++++++++++---------- assets/scripts/components/group.jsx | 9 ++--- assets/scripts/components/modal.jsx | 29 +++++++++++++++ assets/scripts/components/musters.jsx | 2 +- 4 files changed, 66 insertions(+), 27 deletions(-) create mode 100644 assets/scripts/components/modal.jsx diff --git a/assets/scripts/components/card.jsx b/assets/scripts/components/card.jsx index f288af80..98554541 100644 --- a/assets/scripts/components/card.jsx +++ b/assets/scripts/components/card.jsx @@ -1,32 +1,45 @@ 'use strict'; import React from 'react'; +import Modal from './modal.jsx'; const Card = React.createClass({ - render: function(){ - return ( -
    -
    -
    -
    {this.props.data.name}
    -
    {this.props.data.designation}
    -
    {this.props.data.mobile}
    -
    -
    -
    -
    CURRENT
    -
    {this.props.data.current_total}
    + + toggleModal() { + const state = this.state.modalOpen; + this.setState({ modalOpen: !state}); + }, + getInitialState: function(){ + return { + modalOpen: false + }; + }, + render: function(){ + return ( +
    +
    +
    +
    {this.props.data.name}
    +
    {this.props.data.designation}
    +
    {this.props.data.mobile}
    -
    -
    DELAYED
    -
    {this.props.data.delayed_total}
    +
    +
    +
    CURRENT
    +
    {this.props.data.current_total}
    +
    +
    +
    DELAYED
    +
    {this.props.data.delayed_total}
    +
    + + +
    -
    -
    - ); - } + ); + } }); diff --git a/assets/scripts/components/group.jsx b/assets/scripts/components/group.jsx index 00c56c34..5255ca0a 100644 --- a/assets/scripts/components/group.jsx +++ b/assets/scripts/components/group.jsx @@ -5,9 +5,7 @@ import Card from './card.jsx'; const Group = React.createClass({ - filterCards: function(event){ - var updatedList = this.props.data.cards; updatedList = updatedList.filter(function(item){ return item.name.toLowerCase().search(event.target.value.toLowerCase()) !== -1; @@ -18,11 +16,10 @@ const Group = React.createClass({ return { cards: [] }; - }, - componentWillMount: function(){ + }, + componentWillMount: function(){ this.setState({cards: this.props.data.cards}); - }, - + }, render: function(){ return (
    diff --git a/assets/scripts/components/modal.jsx b/assets/scripts/components/modal.jsx new file mode 100644 index 00000000..96cd062e --- /dev/null +++ b/assets/scripts/components/modal.jsx @@ -0,0 +1,29 @@ +'use strict'; + +import React from 'react'; +import {render} from 'react-dom'; + +const Modal = React.createClass({ + + render() { + + const styles = { + modal: { + display : (this.props.show) ? null : 'none', + backgroundColor : 'rgba(255, 255, 255, 0.8)', + } + }; + + return ( +
    + close +
    + { this.props.children } +
    +
    + ); + } + +}); + +export default Modal; diff --git a/assets/scripts/components/musters.jsx b/assets/scripts/components/musters.jsx index 8b4aea54..f071c50e 100644 --- a/assets/scripts/components/musters.jsx +++ b/assets/scripts/components/musters.jsx @@ -36,7 +36,7 @@ const Cards = React.createClass({ return ; }) } -
    +
    ); } }); From d21539dabb1a51677576200ed371ad6111b5bc8a Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Wed, 17 Aug 2016 19:40:23 +0530 Subject: [PATCH 131/314] Add muster details --- assets/scripts/components/card.jsx | 24 +++++++++++++++++++++++- assets/scripts/components/modal.jsx | 2 +- assets/styles/index.scss | 1 + assets/styles/modules/modal.scss | 8 ++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 assets/styles/modules/modal.scss diff --git a/assets/scripts/components/card.jsx b/assets/scripts/components/card.jsx index 98554541..8e33096a 100644 --- a/assets/scripts/components/card.jsx +++ b/assets/scripts/components/card.jsx @@ -34,7 +34,29 @@ const Card = React.createClass({
    - + + + { /* + { + Object.keys(this.props.data.delayed_musters[0]).map(function(key, i) { + return ; + }) + } + */} + { + this.props.data.delayed_musters.map(function(data, i) { + return ( + + { + Object.keys(data).map(function(key, i) { + return ; + }) + } + + ); + }) + } +
    {key}
    {data[key]}
    diff --git a/assets/scripts/components/modal.jsx b/assets/scripts/components/modal.jsx index 96cd062e..f8f59d96 100644 --- a/assets/scripts/components/modal.jsx +++ b/assets/scripts/components/modal.jsx @@ -17,7 +17,7 @@ const Modal = React.createClass({ return (
    close -
    +
    { this.props.children }
    diff --git a/assets/styles/index.scss b/assets/styles/index.scss index 920d323a..a6fda965 100644 --- a/assets/styles/index.scss +++ b/assets/styles/index.scss @@ -39,6 +39,7 @@ Bootstrap Styles @import 'modules/menu'; @import 'modules/message'; @import 'modules/misc'; +@import 'modules/modal'; /* Layouts ---------------------------------------------*/ diff --git a/assets/styles/modules/modal.scss b/assets/styles/modules/modal.scss new file mode 100644 index 00000000..46ca1bfc --- /dev/null +++ b/assets/styles/modules/modal.scss @@ -0,0 +1,8 @@ +.modal-wrapper{ + position: fixed; + top: 60px; + left: 0; + height: 100%; + width: 100%; + z-index: 1000 +} From 0132eadde5a0561927636235910afca9b2aad583 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Wed, 17 Aug 2016 19:57:56 +0530 Subject: [PATCH 132/314] Add style to table --- assets/scripts/components/card.jsx | 11 ++--------- assets/scripts/components/modal.jsx | 2 +- assets/styles/base/typography.scss | 3 +++ assets/styles/modules/modal.scss | 4 ++++ 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/assets/scripts/components/card.jsx b/assets/scripts/components/card.jsx index 8e33096a..ba8a554e 100644 --- a/assets/scripts/components/card.jsx +++ b/assets/scripts/components/card.jsx @@ -34,15 +34,8 @@ const Card = React.createClass({
    - - - { /* - { - Object.keys(this.props.data.delayed_musters[0]).map(function(key, i) { - return ; - }) - } - */} + +
    {key}
    { this.props.data.delayed_musters.map(function(data, i) { return ( diff --git a/assets/scripts/components/modal.jsx b/assets/scripts/components/modal.jsx index f8f59d96..f8431f87 100644 --- a/assets/scripts/components/modal.jsx +++ b/assets/scripts/components/modal.jsx @@ -16,7 +16,7 @@ const Modal = React.createClass({ return (
    - close + X
    { this.props.children }
    diff --git a/assets/styles/base/typography.scss b/assets/styles/base/typography.scss index 29ab1315..09a86ade 100644 --- a/assets/styles/base/typography.scss +++ b/assets/styles/base/typography.scss @@ -23,6 +23,9 @@ h6 { font-weight: lighter; margin-bottom: $spacing-small; } +table{ + width: 100% +} /* Code ------------------------------------------------- */ diff --git a/assets/styles/modules/modal.scss b/assets/styles/modules/modal.scss index 46ca1bfc..ff0ab3ca 100644 --- a/assets/styles/modules/modal.scss +++ b/assets/styles/modules/modal.scss @@ -6,3 +6,7 @@ width: 100%; z-index: 1000 } +.muster-table{ + background: #fff; + text-align: left +} From 99f10ade321199c824c95bb9d41a15f87f6dfc06 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Wed, 17 Aug 2016 20:51:39 +0530 Subject: [PATCH 133/314] Add table style --- assets/scripts/components/card.jsx | 17 ++---------- assets/scripts/components/table.jsx | 40 +++++++++++++++++++++++++++++ assets/styles/base/typography.scss | 30 +++++++++++++++++++--- assets/styles/modules/modal.scss | 11 ++++++-- 4 files changed, 78 insertions(+), 20 deletions(-) create mode 100644 assets/scripts/components/table.jsx diff --git a/assets/scripts/components/card.jsx b/assets/scripts/components/card.jsx index ba8a554e..27b23b24 100644 --- a/assets/scripts/components/card.jsx +++ b/assets/scripts/components/card.jsx @@ -2,6 +2,7 @@ import React from 'react'; import Modal from './modal.jsx'; +import Table from './table.jsx'; const Card = React.createClass({ @@ -35,21 +36,7 @@ const Card = React.createClass({
    -
    - { - this.props.data.delayed_musters.map(function(data, i) { - return ( - - { - Object.keys(data).map(function(key, i) { - return ; - }) - } - - ); - }) - } -
    {data[key]}
    +
    diff --git a/assets/scripts/components/table.jsx b/assets/scripts/components/table.jsx new file mode 100644 index 00000000..17c0cc9e --- /dev/null +++ b/assets/scripts/components/table.jsx @@ -0,0 +1,40 @@ +'use strict'; + +import React from 'react'; + +const Table = React.createClass({ + + render: function(){ + return ( + + + + + + + + + + + + + { + this.props.data.map(function(data, i) { + return ( + + { + Object.keys(data).map(function(key, i) { + return ; + }) + } + + ); + }) + } + +
    123456
    {data[key]}
    + ); + } +}); + +export default Table; diff --git a/assets/styles/base/typography.scss b/assets/styles/base/typography.scss index 09a86ade..b465bcc2 100644 --- a/assets/styles/base/typography.scss +++ b/assets/styles/base/typography.scss @@ -5,15 +5,19 @@ a { color: $color-accent; text-decoration: none; } + a:hover { color: darken($color-accent, 10%); } + /* Headings ------------------------------------------------- */ -h1{ + +h1 { font-weight: normal } + h2, h3, h4, @@ -23,10 +27,29 @@ h6 { font-weight: lighter; margin-bottom: $spacing-small; } -table{ - width: 100% + + +/* Tables +–––––––––––––––––––––––––––––––––––––––––––––––––– */ + +th, +td { + padding: 12px 15px; + text-align: left; + border-bottom: 1px solid #E1E1E1; } +th:first-child, +td:first-child { + padding-left: 0; +} + +th:last-child, +td:last-child { + padding-right: 0; +} + + /* Code ------------------------------------------------- */ @@ -39,6 +62,7 @@ code { border: 1px solid #E1E1E1; border-radius: 4px; } + pre > code { display: block; padding: 1rem 1.5rem; diff --git a/assets/styles/modules/modal.scss b/assets/styles/modules/modal.scss index ff0ab3ca..dfd1af25 100644 --- a/assets/styles/modules/modal.scss +++ b/assets/styles/modules/modal.scss @@ -6,7 +6,14 @@ width: 100%; z-index: 1000 } -.muster-table{ +.modal-item { background: #fff; - text-align: left + padding: 30px; + box-shadow: 0 1px 4px rgba(0,0,0,.04); + border: 1px solid rgba(0,0,0,.09); + border-radius: 4px; +} +.muster-table{ + text-align: left; + width: 100%; } From fda32491c07a7249aa296d740a5b606655834e0e Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Wed, 17 Aug 2016 21:10:50 +0530 Subject: [PATCH 134/314] Move musters to component will mount --- assets/scripts/components/musters.jsx | 2 +- assets/scripts/components/table.jsx | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/assets/scripts/components/musters.jsx b/assets/scripts/components/musters.jsx index f071c50e..798dba27 100644 --- a/assets/scripts/components/musters.jsx +++ b/assets/scripts/components/musters.jsx @@ -25,7 +25,7 @@ const Cards = React.createClass({ musters: [] }; }, - componentDidMount: function() { + componentWillMount: function() { this.fetchCards(); }, render: function(){ diff --git a/assets/scripts/components/table.jsx b/assets/scripts/components/table.jsx index 17c0cc9e..a607b488 100644 --- a/assets/scripts/components/table.jsx +++ b/assets/scripts/components/table.jsx @@ -9,12 +9,11 @@ const Table = React.createClass({ - - - - - - + { + this.props.data.length > 0 && Object.keys(this.props.data[0]).map(function(key){ + return ; + }) + } From 95852604447b57bcc3936e6b2314183546c10f13 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 18 Aug 2016 09:45:44 +0530 Subject: [PATCH 135/314] Add muster details --- assets/scripts/components/card.jsx | 3 +- assets/scripts/components/modal.jsx | 3 +- assets/scripts/components/table.jsx | 51 +++++++++++++++-------------- assets/styles/modules/modal.scss | 7 ++++ assets/styles/views/musters.scss | 2 +- 5 files changed, 39 insertions(+), 27 deletions(-) diff --git a/assets/scripts/components/card.jsx b/assets/scripts/components/card.jsx index 27b23b24..96ede09d 100644 --- a/assets/scripts/components/card.jsx +++ b/assets/scripts/components/card.jsx @@ -36,7 +36,8 @@ const Card = React.createClass({ -
    123456{key}
    +
    +
    diff --git a/assets/scripts/components/modal.jsx b/assets/scripts/components/modal.jsx index f8431f87..56e577d8 100644 --- a/assets/scripts/components/modal.jsx +++ b/assets/scripts/components/modal.jsx @@ -16,8 +16,9 @@ const Modal = React.createClass({ return (
    - X +
    + { this.props.children }
    diff --git a/assets/scripts/components/table.jsx b/assets/scripts/components/table.jsx index a607b488..985b95ad 100644 --- a/assets/scripts/components/table.jsx +++ b/assets/scripts/components/table.jsx @@ -6,32 +6,35 @@ const Table = React.createClass({ render: function(){ return ( - - - +
    +

    {this.props.title}

    +
    + + + { + this.props.data.length > 0 && Object.keys(this.props.data[0]).map(function(key){ + return ; + }) + } + + + { - this.props.data.length > 0 && Object.keys(this.props.data[0]).map(function(key){ - return ; + this.props.data.map(function(data, i) { + return ( + + { + Object.keys(data).map(function(key, i) { + return ; + }) + } + + ); }) - } - - - - { - this.props.data.map(function(data, i) { - return ( - - { - Object.keys(data).map(function(key, i) { - return ; - }) - } - - ); - }) - } - -
    {key}
    {key}
    {data[key]}
    {data[key]}
    + } + + + ); } }); diff --git a/assets/styles/modules/modal.scss b/assets/styles/modules/modal.scss index dfd1af25..9bc7e084 100644 --- a/assets/styles/modules/modal.scss +++ b/assets/styles/modules/modal.scss @@ -12,8 +12,15 @@ box-shadow: 0 1px 4px rgba(0,0,0,.04); border: 1px solid rgba(0,0,0,.09); border-radius: 4px; + max-height: 80%; + margin-top: 10px; + overflow-y: scroll } .muster-table{ text-align: left; width: 100%; } +.modal-close{ + font-size: 2em; + cursor: pointer +} diff --git a/assets/styles/views/musters.scss b/assets/styles/views/musters.scss index b635db85..9379beee 100644 --- a/assets/styles/views/musters.scss +++ b/assets/styles/views/musters.scss @@ -7,7 +7,7 @@ } .group-head .search-bar { - margin-top: 8px + margin-top: 4px } .card { min-height: 300px; From c65e406d77f70173f3e4b34ed58ec4a6f3e52d82 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 18 Aug 2016 10:35:20 +0530 Subject: [PATCH 136/314] Fix password response --- app/controllers/api/account.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/account.js b/app/controllers/api/account.js index ab601e47..b1383dec 100644 --- a/app/controllers/api/account.js +++ b/app/controllers/api/account.js @@ -48,7 +48,12 @@ exports.postChangePassword = { password: Crypto.createHash('md5').update(request.payload.newPassword).digest('hex') }).then(function() { request.cookieAuth.clear(); - return reply('Password changed successfully. Please login with new password'); + + var msg = { + 'statusCode': 200, + 'message': 'Password changed successfully. Please login with new password' + }; + return reply(msg); }); } else { // User not fond in database From dd8011f594daad50c87463c4a2c7411c1bfd5d75 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 18 Aug 2016 10:51:02 +0530 Subject: [PATCH 137/314] Fix login api typo --- app/controllers/api/login.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/login.js b/app/controllers/api/login.js index a60175ad..82eb2667 100644 --- a/app/controllers/api/login.js +++ b/app/controllers/api/login.js @@ -19,7 +19,7 @@ exports.postForm = { payload: { // payload for POST, query for GET username: Joi.string().min(3).max(20), password: Joi.string().min(6).max(20), - google_Account: Joi.string().min(6).max(60).optional() + google_account: Joi.string().min(6).max(60).optional() }, failAction: function(request, reply, source, error) { // Username, passowrd minimum validation failed From d67c4b527355d7105dfdf373fe0118e405ed306b Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 18 Aug 2016 10:51:27 +0530 Subject: [PATCH 138/314] Add dark theme --- assets/scripts/components/modal.jsx | 4 +--- assets/scripts/index.js | 3 +++ assets/scripts/lib/active-link.js | 9 +++++++++ assets/styles/base/base.scss | 1 + assets/styles/layout/metabar.scss | 6 +++--- assets/styles/modules/modal.scss | 13 +++++++------ assets/styles/scales/color.scss | 11 +++++++++-- assets/styles/views/musters.scss | 4 ++-- 8 files changed, 35 insertions(+), 16 deletions(-) create mode 100644 assets/scripts/lib/active-link.js diff --git a/assets/scripts/components/modal.jsx b/assets/scripts/components/modal.jsx index 56e577d8..a6da8023 100644 --- a/assets/scripts/components/modal.jsx +++ b/assets/scripts/components/modal.jsx @@ -9,14 +9,12 @@ const Modal = React.createClass({ const styles = { modal: { - display : (this.props.show) ? null : 'none', - backgroundColor : 'rgba(255, 255, 255, 0.8)', + display : (this.props.show) ? null : 'none' } }; return (
    diff --git a/assets/scripts/components/comparison-chart.jsx b/assets/scripts/components/comparison-chart.jsx index dfb4538f..8e004c40 100644 --- a/assets/scripts/components/comparison-chart.jsx +++ b/assets/scripts/components/comparison-chart.jsx @@ -131,12 +131,12 @@ const ComparisonChart = React.createClass({

    From 8a0e231ca655468ab233eeb0b903d8a9911afaf7 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 26 Aug 2016 13:00:43 +0530 Subject: [PATCH 199/314] Apply translation to overview components --- app/controllers/overview/overview.js | 5 +---- app/helpers/overview_parser.js | 2 +- app/locales/en_US/v1.js | 6 +++--- assets/scripts/components/tile.jsx | 6 +++--- assets/scripts/containers/overview.jsx | 12 ++++++++---- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/app/controllers/overview/overview.js b/app/controllers/overview/overview.js index fed30aa4..cc191525 100644 --- a/app/controllers/overview/overview.js +++ b/app/controllers/overview/overview.js @@ -14,7 +14,6 @@ exports.getData = { handler: function(request, reply) { var sequelize = request.server.plugins.sequelize.db.sequelize; - var role = request.auth.credentials.role; var userId = request.auth.credentials.id; var queryString = Queries.overview(userId, role); @@ -23,12 +22,10 @@ exports.getData = { type: sequelize.QueryTypes.SELECT }).then(function(rows) { - // Database query takes the role as an input (district or block). Parser returns generic "region_code", "region_name" keys. - var data = OverviewParser.parser(rows); + data.translation = Translate('/web/overview', request.auth.credentials, null); reply(data); - }); } }; diff --git a/app/helpers/overview_parser.js b/app/helpers/overview_parser.js index ad00a537..ec5509b5 100644 --- a/app/helpers/overview_parser.js +++ b/app/helpers/overview_parser.js @@ -17,7 +17,7 @@ exports.parser = function(rows) { 'current_total': v[0].current_total, 'delayed_total': v[0].delayed_total, 'days_to_payment': v[0].days_to_payment - } + }; }) .entries(overviewResponse) .map(function(d) { diff --git a/app/locales/en_US/v1.js b/app/locales/en_US/v1.js index 934d5fe4..bddbc471 100644 --- a/app/locales/en_US/v1.js +++ b/app/locales/en_US/v1.js @@ -4,9 +4,9 @@ module.exports = { $meta: 'English translation file', web: { overview: { - current: 'Current', - delayed: 'Delayed', - days_to_payment: 'Days to payment', + current: 'CUREENT', + delayed: 'DELAYED', + days_to_payment: 'DAYS TO PAYMENT', description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' } }, diff --git a/assets/scripts/components/tile.jsx b/assets/scripts/components/tile.jsx index 1f60c14b..3c00feab 100644 --- a/assets/scripts/components/tile.jsx +++ b/assets/scripts/components/tile.jsx @@ -10,15 +10,15 @@ const Tile = React.createClass({
    {this.props.data.region_name}
    -
    CURRENT
    +
    {this.props.translation.current}
    {this.props.data.current_total}
    -
    DELAYED
    +
    {this.props.translation.delayed}
    {this.props.data.delayed_total}
    -
    DAYS TO PAYMENT
    +
    {this.props.translation.days_to_payment}
    {this.props.data.days_to_payment}
    diff --git a/assets/scripts/containers/overview.jsx b/assets/scripts/containers/overview.jsx index 78dbe22b..f07b0481 100644 --- a/assets/scripts/containers/overview.jsx +++ b/assets/scripts/containers/overview.jsx @@ -12,7 +12,10 @@ const Overview = React.createClass({ var _this = this; D3.json(_this.props.url) .on('load', function(json) { - _this.setState({overview: json.overview}); + _this.setState({ + overview: json.overview, + translation: json.translation + }); }) .on('error', function(error) { console.error(_this.props.url, status, error.toString()); @@ -29,11 +32,12 @@ const Overview = React.createClass({ this.fetchData(); }, render: function(){ + var _this = this; return (
    - { - this.state.overview.map(function(data, i) { - return ; + { + _this.state.overview.map(function(data, i) { + return ; }) }
    From 78b89d7961efcfb1755ae1bc0d22d74a95aac435 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 26 Aug 2016 13:11:56 +0530 Subject: [PATCH 200/314] Apply hindi translation for overview --- app/controllers/overview/overview.js | 1 - app/locales/hi/v1.js | 165 +-------------------------- 2 files changed, 5 insertions(+), 161 deletions(-) diff --git a/app/controllers/overview/overview.js b/app/controllers/overview/overview.js index cc191525..d8c69a12 100644 --- a/app/controllers/overview/overview.js +++ b/app/controllers/overview/overview.js @@ -24,7 +24,6 @@ exports.getData = { var data = OverviewParser.parser(rows); data.translation = Translate('/web/overview', request.auth.credentials, null); - reply(data); }); } diff --git a/app/locales/hi/v1.js b/app/locales/hi/v1.js index 0f2f273d..04cafb87 100644 --- a/app/locales/hi/v1.js +++ b/app/locales/hi/v1.js @@ -2,167 +2,12 @@ module.exports = { $meta: 'Hindi translation file', - profile: { - firstname: 'मूल नाम', - lastname: 'उपनाम', - profile: 'प्रोफ़ाइल', - account: 'अकाउंट', - work_email: 'औपचारिक e-mail', - mobile: 'मोबाइल नंबर', - personal_email: 'निजी e-mail', - lang : 'भाषा', - settings: 'सेट्टिंग्स', - logout: 'लौग आउट', - profile_settings: 'आपकी प्रोफ़ाइल सेट्टिंग्स', - email_settings: 'E-Mail सेट्टिंग्स', - primary_email_msg: 'आपके अकाउंट से संबंधित संदेशों और इंटरनेट-संबंधित प्रक्रियाओं के लिए आपके मुख्य e-mail ID का उपयोग किया जाएगा.', - save: 'अद्यतन (update)', - your_primary_email: 'आपका मुख्य e-mail ID', - change_pass: 'पासवर्ड बदलें', - old_pass: 'पुराना पासवर्ड ', - new_pass: 'नया पासवर्ड ', - pass_confirm:'नये पासवर्ड को सत्यापित करें', - forgot_pass: 'मैं अपना पासवर्ड भूल गयी/गया' - }, - navigation: { - overview: { - $filter: 'role', - district: 'ज़िला प्रदर्शन', - block: 'प्रखंड/जनपद प्रदर्शन', - $default: 'अवलोकन प्रदर्शन' - }, - discrete: { - $filter: 'role', - district: 'प्रखंड/जनपद प्रदर्शन', - block: 'पंचायत प्रदर्शन', - $default: 'अलहदा प्रदर्शन' - }, - current: 'वर्तमान मस्टर्स', - delayed: 'विलंबित मस्टर्स' - }, - notifications : { - read : 'पठित संदेश', - unread : 'अपठित संदेश', - message: { - 1: { - $filter: 'role', - block: [' प्रखंड/जनपद में ',' तारीख को ',' MGNREGA भुगतान हुए |'], - district: [' ज़िला में ',' तारीख को ',' MGNREGA भुगतान हुए |'] - }, - 2: { - main: ['औसतन, मस्टर रोल बंद होने से बैंक की कारवाई के समापन के बीच ',' दिन लगे, जो की सरकार द्वारा नियमित 15-दिन की सीमा ',' है |'], - comparison: ['से ज़्यादा','के बराबर','से कम'] - } - } - }, - browser_msg: 'आपका browser इस वेबसाइट के लिए अनुकूल नहीं है. PayDash चलाने के लिए Chrome, Firefox या Internet Explorer 9 या ऊंचे संस्करण का उपयोग करें.', - messages: { - loading: 'डाटा लोड हो रहा है...', - not_found: 'पृष्ठ नहीं मिला। Paydash टीम से संपर्क करें.' - }, - time_selector :{ - '1': 'सारी उपलब्ध तिथियाँ', - '2': 'पिछले 60 दिन', - '3': 'पिछले 30 दिन' - }, - payment_steps: { - '1': 'मस्टर रोल बंद से डाटा एंट्री का समय', - '2': 'डाटा एंट्री से वेज लिस्ट बनाने का समय', - '3': 'वेज लिस्ट बनाने से वेज लिस्ट भेजने का समय', - '4': 'वेज लिस्ट भेजने से FTO बनाने का समय', - '5': 'FTO बनाने से पहले हस्ताक्षर का समय', - '6': 'पहले हस्ताक्षर से दूसरे हस्ताक्षर का समय', - '7': 'दूसरे हस्ताक्षर से बैंक की कारवाई के समापन का समय' - }, - payment_steps_labels: [ - 'मस्टर रोल बंद से डाटा एंट्री का समय', - 'डाटा एंट्री से वेज लिस्ट बनाने का समय', - 'वेज लिस्ट बनाने से वेज लिस्ट भेजने का समय', - 'वेज लिस्ट भेजने से FTO बनाने का समय', - 'FTO बनाने से पहले हस्ताक्षर का समय', - 'पहले हस्ताक्षर से दूसरे हस्ताक्षर का समय', - 'दूसरे हस्ताक्षर से बैंक की कारवाई के समापन का समय' - ], - compare_chart_labels:{ - 'state': 'राज्य औसत', - 'district': 'ज़िला औसत', - 'block': 'प्रखंड/जनपद औसत' - }, - y_axis_labels: 'प्रक्रिया पूरी करने में लगे दिन', - total_trans :"तिथि : कुल भुगतानों की संख्या-", - performance: { + web: { overview: { - chart_a: { - title: { - $filter: 'role', - district: 'आपके ज़िले का प्रदर्शन', - block: 'आपके प्रखंड/जनपद का प्रदर्शन', - $default: 'अवलोकन प्रदर्शन' - }, - description: { - $filter: 'role', - district: 'आपके ज़िले में मज़दूरी भुगतान के हर एक पड़ाव पर लगे औसत दिन', - block: 'आपके प्रखंड/जनपद में मज़दूरी भुगतान के हर एक पड़ाव पर लगे औसत दिन', - $default: 'आपके क्षेत्रों में मज़दूरी भुगतान के हर एक पड़ाव पर लगे औसत दिन' - } - }, - chart_b: { - title: { - $filter: 'role', - district: 'आपके प्रदर्शन की तुलना', - block: 'आपके प्रदर्शन की तुलना', - $default: 'आपके प्रदर्शन की तुलना' - }, - description: { - $filter: 'role', - district: 'अपने ज़िले के औसत प्रदर्शन की तुलना राज्य के औसत प्रदर्शन से करें', - block: 'अपने प्रखंड/जनपद के औसत प्रदर्शन की तुलना ज़िले और राज्य के औसत प्रदर्शन से करें ', - $default: 'अपने प्रखंड/जनपद के औसत प्रदर्शन की तुलना अन्य क्षेत्रों के औसत प्रदर्शन से करें' - } - }, - tooltip: 'यह ग्राफ़ MGNREGA मज़दूरी भुगतान में लगा औसत समय दिखाता है| वर्णित तिथियों पर हुए भुगतान में लगे समय को 7 पड़ावों में बाटा गया है| इसलिए, केवल पूरे हुए भुगतान का डाटा दिखाया जा रहा है|', - }, - discrete:{ - sub_heading: { - '1' : { - $filter: 'role', - block: 'आपके जनपद/प्रखंड की पंचायत', - district: 'आपके ज़िले में प्रखंड/पंचायत' - }, - '2' : 'का प्रदर्शन' - }, - subtitle: { - $filter: 'role', - block: 'आपकी पंचायतों में मज़दूरी भुगतान की प्रक्रिया के हर एक पड़ाव में लगा औसत समय', - district: 'आपके प्रखंडों/पंचायतों में मज़दूरी भुगतान की प्रक्रिया के हर एक पड़ाव में लगा औसत समय', - $default :'अपने क्षेत्रों में मज़दूरी भुगतान की प्रक्रिया के हर एक पड़ाव में लगा औसत समय' - }, - tooltip: 'यह ग्राफ़ MGNREGA मज़दूरी भुगतान में लगा औसत समय दिखाता है| वर्णित तिथियों पर हुए भुगतान में लगे समय को 7 पड़ावों में बाटा गया है| इसलिए, केवल पूरे हुए भुगतान का डाटा दिखाया जा रहा है|', - ta_message: 'आपके प्रखंड/जनपद में कुछ TAs/SEs/JEs और उनकी पंचायतों के नाम MGNREGA वेबसाइट पर अपडेट नहीं किए गये हैं| इस के परिणाम स्वरूप, हम आपको आपके प्रखंड/जनपद के सभी TAs/SEs/JEs के प्रदर्शन की जानकारी नहीं दे सकते| यह जानकारी पाने के लिए कृपया nrega.nic.in पर सभी TAs/SEs/JEs और उनकी पंचायतों के नाम भरें|', - grs_message: 'आपके प्रखंड/जनपद में कुछ GRSs और उनकी पंचायतों के नाम MGNREGA वेबसाइट पर अपडेट नहीं किए गये हैं| इस के परिणाम स्वरूप, हम आपको आपके प्रखंड/जनपद के सभी GRSs के प्रदर्शन की जानकारी नहीं दे सकते| यह जानकारी पाने के लिए कृपया nrega.nic.in पर सभी GRSs और उनकी पंचायतों के नाम भरें|', - panchayat_chart_placeholder: 'भुगतान के प्रदर्शन को देखने के लिए एक पंचायत या प्रखंड/जनपद का चयन करें ', - grouping_selectors: { - no: 'बिना कोई वर्गीकरण', - ta:'वर्ग: उप यंत्री', - grs: 'वर्ग: GRS' - }, - sidebar : { - total_trans: 'कुल भुगतान ', - avg_days: 'पंचायतों में मस्टर रोल बंद से डाटा एंट्री में लगा समय (औसत)' - } - } - }, - musters: { - current: { - title: 'आज बंद हो रहे मस्टर्स' - }, - delayed:{ - title: 'विलंबित मस्टर्स', - t_2: 'अटेंडेन्स नहीं भरी गयी (T+2)', - t_5: 'MB नहीं भरी गयी (T+5)', - t_6: 'वेज लिस्ट नहीं भेजी गयी (T+6)', - t_7: 'FTO पर पहला हस्ताक्षर नहीं हुआ (T+7)', - t_8: 'FTO पर दूसरा हस्ताक्षर नहीं हुआ (T+8)' + current: 'वर्तमान मस्टर्स', + delayed: 'विलंबित मस्टर्स', + days_to_payment: 'भुगतान के लिए दिन', + description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' } }, app: { From 53e593dcc1bc8301b750b7fe53e1d534ab4ce913 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 26 Aug 2016 13:17:55 +0530 Subject: [PATCH 201/314] Generalize musters API --- app/helpers/musters_parser.js | 20 ++++++++++---------- assets/scripts/containers/musters.jsx | 4 +++- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app/helpers/musters_parser.js b/app/helpers/musters_parser.js index 5b265d3c..116c209a 100644 --- a/app/helpers/musters_parser.js +++ b/app/helpers/musters_parser.js @@ -6,9 +6,7 @@ const D3 = require('d3'); exports.block = function(rows) { var cardsResponse = D3.values(rows[0]); - var stateResponse = D3.values(rows[1]); - var stateCode = stateResponse[0].state_code; // Nest the cards response @@ -54,8 +52,9 @@ exports.block = function(rows) { .entries(cardsResponse) .map(function(d) { return { - 'block_code': d.key.substr(0,7), - 'block_name': d.key.substr(7), + 'region_type': 'block', + 'region_code': d.key.substr(0,7), + 'region_name': d.key.substr(7), 'cards': d.values.map(function(e) { return e.values; }) @@ -67,7 +66,7 @@ exports.block = function(rows) { }; return data; -} +}; exports.district = function(rows) { @@ -76,7 +75,7 @@ exports.district = function(rows) { // Nest the cards response var cards = D3.nest() .key(function(d) { - return d.district_code + d.district_name + return d.district_code + d.district_name; }) .key(function(d) { return d.block_code; @@ -85,7 +84,7 @@ exports.district = function(rows) { return { 'officers': v.map(function(d) { return { - name: d.id == null ? 'No Data' : d.firstname + ' ' + d.lastname, + name: d.id === null ? 'No Data' : d.firstname + ' ' + d.lastname, designation: d.designation, mobile: d.mobile }; @@ -109,8 +108,9 @@ exports.district = function(rows) { .entries(cardsResponse) .map(function(d) { return { - 'district_code': d.key.substr(0,4), - 'district_name': d.key.substr(4), + 'region_type': 'district', + 'region_code': d.key.substr(0,4), + 'region_name': d.key.substr(4), 'data': d.values.map(function(e) { return e.values; }) @@ -122,4 +122,4 @@ exports.district = function(rows) { }; return data; -} +}; diff --git a/assets/scripts/containers/musters.jsx b/assets/scripts/containers/musters.jsx index d6cdcd7b..a0c655c5 100644 --- a/assets/scripts/containers/musters.jsx +++ b/assets/scripts/containers/musters.jsx @@ -12,7 +12,9 @@ const Musters = React.createClass({ var _this = this; D3.json(_this.props.url) .on('load', function(json) { - _this.setState({musters: json.musters}); + _this.setState({ + musters: json.musters + }); }) .on('error', function(error) { console.error(_this.props.url, status, error.toString()); From a870022c3b28ba2d409c991862794beb32ba8d86 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 26 Aug 2016 14:34:28 +0530 Subject: [PATCH 202/314] Restructure ract components --- app/helpers/musters_parser.js | 2 +- assets/scripts/components/{ => global}/modal.jsx | 0 assets/scripts/components/{ => musters}/card.jsx | 2 +- assets/scripts/components/{ => musters}/group.jsx | 2 +- assets/scripts/components/{ => musters}/table.jsx | 0 assets/scripts/components/{ => overview}/tile.jsx | 0 .../components/{ => performance}/comparison-chart.jsx | 6 +++--- .../overview-chart.jsx} | 8 ++++---- assets/scripts/components/{ => performance}/subnav.jsx | 2 +- assets/scripts/containers/musters.jsx | 2 +- assets/scripts/containers/overview.jsx | 2 +- assets/scripts/containers/performance.jsx | 8 ++++---- 12 files changed, 17 insertions(+), 17 deletions(-) rename assets/scripts/components/{ => global}/modal.jsx (100%) rename assets/scripts/components/{ => musters}/card.jsx (97%) rename assets/scripts/components/{ => musters}/group.jsx (98%) rename assets/scripts/components/{ => musters}/table.jsx (100%) rename assets/scripts/components/{ => overview}/tile.jsx (100%) rename assets/scripts/components/{ => performance}/comparison-chart.jsx (98%) rename assets/scripts/components/{performance-chart.jsx => performance/overview-chart.jsx} (97%) rename assets/scripts/components/{ => performance}/subnav.jsx (96%) diff --git a/app/helpers/musters_parser.js b/app/helpers/musters_parser.js index 116c209a..ccc9142f 100644 --- a/app/helpers/musters_parser.js +++ b/app/helpers/musters_parser.js @@ -111,7 +111,7 @@ exports.district = function(rows) { 'region_type': 'district', 'region_code': d.key.substr(0,4), 'region_name': d.key.substr(4), - 'data': d.values.map(function(e) { + 'cards': d.values.map(function(e) { return e.values; }) }; diff --git a/assets/scripts/components/modal.jsx b/assets/scripts/components/global/modal.jsx similarity index 100% rename from assets/scripts/components/modal.jsx rename to assets/scripts/components/global/modal.jsx diff --git a/assets/scripts/components/card.jsx b/assets/scripts/components/musters/card.jsx similarity index 97% rename from assets/scripts/components/card.jsx rename to assets/scripts/components/musters/card.jsx index 96ede09d..34ca691b 100644 --- a/assets/scripts/components/card.jsx +++ b/assets/scripts/components/musters/card.jsx @@ -1,7 +1,7 @@ 'use strict'; import React from 'react'; -import Modal from './modal.jsx'; +import Modal from '../global/modal.jsx'; import Table from './table.jsx'; const Card = React.createClass({ diff --git a/assets/scripts/components/group.jsx b/assets/scripts/components/musters/group.jsx similarity index 98% rename from assets/scripts/components/group.jsx rename to assets/scripts/components/musters/group.jsx index 5255ca0a..0eae61fc 100644 --- a/assets/scripts/components/group.jsx +++ b/assets/scripts/components/musters/group.jsx @@ -25,7 +25,7 @@ const Group = React.createClass({
    -

    {this.props.data.block_name}

    +

    {this.props.data.region_name}

    { diff --git a/assets/scripts/components/table.jsx b/assets/scripts/components/musters/table.jsx similarity index 100% rename from assets/scripts/components/table.jsx rename to assets/scripts/components/musters/table.jsx diff --git a/assets/scripts/components/tile.jsx b/assets/scripts/components/overview/tile.jsx similarity index 100% rename from assets/scripts/components/tile.jsx rename to assets/scripts/components/overview/tile.jsx diff --git a/assets/scripts/components/comparison-chart.jsx b/assets/scripts/components/performance/comparison-chart.jsx similarity index 98% rename from assets/scripts/components/comparison-chart.jsx rename to assets/scripts/components/performance/comparison-chart.jsx index 8e004c40..d3e7d246 100644 --- a/assets/scripts/components/comparison-chart.jsx +++ b/assets/scripts/components/performance/comparison-chart.jsx @@ -1,11 +1,11 @@ 'use strict'; import React from 'react'; -import MG from '../lib/mg'; +import MG from '../../lib/mg'; const D3 = require('d3'); -const Parser = require('../lib/parser'); -const Region = require('../lib/region'); +const Parser = require('../../lib/parser'); +const Region = require('../../lib/region'); const ComparisonChart = React.createClass({ diff --git a/assets/scripts/components/performance-chart.jsx b/assets/scripts/components/performance/overview-chart.jsx similarity index 97% rename from assets/scripts/components/performance-chart.jsx rename to assets/scripts/components/performance/overview-chart.jsx index dcc4e49e..8b6a9287 100644 --- a/assets/scripts/components/performance-chart.jsx +++ b/assets/scripts/components/performance/overview-chart.jsx @@ -1,12 +1,12 @@ 'use strict'; import React from 'react'; -import MG from '../lib/mg'; +import MG from '../../lib/mg'; const D3 = require('d3'); -const Parser = require('../lib/parser'); +const Parser = require('../../lib/parser'); -const PerformanceChart = React.createClass({ +const OverviewChart = React.createClass({ loadChart: function(){ @@ -117,7 +117,7 @@ const PerformanceChart = React.createClass({ }); -export default PerformanceChart; +export default OverviewChart; diff --git a/assets/scripts/components/subnav.jsx b/assets/scripts/components/performance/subnav.jsx similarity index 96% rename from assets/scripts/components/subnav.jsx rename to assets/scripts/components/performance/subnav.jsx index 10a5d351..3fa7d844 100644 --- a/assets/scripts/components/subnav.jsx +++ b/assets/scripts/components/performance/subnav.jsx @@ -3,7 +3,7 @@ import React from 'react'; import Select from 'react-select'; -const Regions = require('../lib/region'); +const Regions = require('../../lib/region'); const Subnav = React.createClass({ diff --git a/assets/scripts/containers/musters.jsx b/assets/scripts/containers/musters.jsx index a0c655c5..53b3607b 100644 --- a/assets/scripts/containers/musters.jsx +++ b/assets/scripts/containers/musters.jsx @@ -1,7 +1,7 @@ 'use strict'; import React from 'react'; -import Group from '../components/group.jsx'; +import Group from '../components/musters/group.jsx'; const D3= require('d3'); diff --git a/assets/scripts/containers/overview.jsx b/assets/scripts/containers/overview.jsx index f07b0481..f5f04de0 100644 --- a/assets/scripts/containers/overview.jsx +++ b/assets/scripts/containers/overview.jsx @@ -1,7 +1,7 @@ 'use strict'; import React from 'react'; -import Tile from '../components/tile.jsx'; +import Tile from '../components/overview/tile.jsx'; const D3= require('d3'); diff --git a/assets/scripts/containers/performance.jsx b/assets/scripts/containers/performance.jsx index 3cf89520..766057fe 100644 --- a/assets/scripts/containers/performance.jsx +++ b/assets/scripts/containers/performance.jsx @@ -1,9 +1,9 @@ 'use strict'; import React from 'react'; -import Subnav from '../components/subnav.jsx'; -import PerformanceChart from '../components/performance-chart.jsx'; -import ComparisonChart from '../components/comparison-chart.jsx'; +import Subnav from '../components/performance/subnav.jsx'; +import OverviewChart from '../components/performance/overview-chart.jsx'; +import ComparisonChart from '../components/performance/comparison-chart.jsx'; const D3= require('d3'); @@ -45,7 +45,7 @@ const Overview = React.createClass({ return (
    - +
    From 125ae153e9f8c36d8dd78624439de5bbc40ea86a Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 26 Aug 2016 15:56:53 +0530 Subject: [PATCH 203/314] Apply translation for muster api --- app/controllers/musters/musters.js | 6 ++---- app/locales/en_US/v1.js | 6 ++++++ assets/scripts/containers/musters.jsx | 8 +++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/controllers/musters/musters.js b/app/controllers/musters/musters.js index a0e0eba2..40970aa3 100644 --- a/app/controllers/musters/musters.js +++ b/app/controllers/musters/musters.js @@ -22,15 +22,13 @@ exports.getData = { }).then(function(rows) { var data; if (role === 'block') { - data = MustersParser.block(rows); - } else if (role === 'district') { - data = MustersParser.district(rows); - } + data.translation = Translate('/web/musters', request.auth.credentials, null); + return reply(data); }); diff --git a/app/locales/en_US/v1.js b/app/locales/en_US/v1.js index bddbc471..b605f03d 100644 --- a/app/locales/en_US/v1.js +++ b/app/locales/en_US/v1.js @@ -8,6 +8,12 @@ module.exports = { delayed: 'DELAYED', days_to_payment: 'DAYS TO PAYMENT', description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' + }, + musters: { + $filter: 'role', + district: 'Muster translations', + block: 'Muster translations', + $default: 'Muster translations' } }, app: { diff --git a/assets/scripts/containers/musters.jsx b/assets/scripts/containers/musters.jsx index 53b3607b..bdb9ae5e 100644 --- a/assets/scripts/containers/musters.jsx +++ b/assets/scripts/containers/musters.jsx @@ -13,7 +13,8 @@ const Musters = React.createClass({ D3.json(_this.props.url) .on('load', function(json) { _this.setState({ - musters: json.musters + musters: json.musters, + translation: json.translation }); }) .on('error', function(error) { @@ -31,11 +32,12 @@ const Musters = React.createClass({ this.fetchMusters(); }, render: function(){ + var _this = this; return (
    { - this.state.musters.map(function(data, i) { - return ; + _this.state.musters.map(function(data, i) { + return ; }) }
    From b589fd1d89d93da33c52947fca4669f27061d33e Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 26 Aug 2016 15:58:41 +0530 Subject: [PATCH 204/314] Cleanup web translations from V2 --- app/locales/en_US/v2.js | 159 ---------------------------------------- app/locales/hi/v1.js | 6 ++ 2 files changed, 6 insertions(+), 159 deletions(-) diff --git a/app/locales/en_US/v2.js b/app/locales/en_US/v2.js index 227e45c9..7aab5a42 100644 --- a/app/locales/en_US/v2.js +++ b/app/locales/en_US/v2.js @@ -2,165 +2,6 @@ module.exports = { $meta: 'English translation file', - profile: { - firstname: 'First Name', - lastname: 'Last Name', - profile: 'Profile', - account: 'Account', - work_email: 'Work Email', - mobile: 'Mobile', - personal_email: 'Personal Email', - lang : 'Language', - settings: 'Settings', - logout: 'Logout', - profile_settings: 'Profile Settings', - email_settings: 'Email Settings', - primary_email_msg: 'Your primary email address will be used for account-related notifications as well as any web-based operations.', - save: 'Update', - your_primary_email: 'Your primary email', - change_pass: 'Change password', - old_pass: 'Old password', - new_pass: 'New password', - pass_confirm:'Verify new password', - forgot_pass: 'I forgot my password' - }, - navigation: { - overview: { - $filter: 'role', - district: 'District Performance', - block: 'Block Performance', - $default: 'Overview Performance' - }, - discrete: { - $filter: 'role', - district: 'Block Performance', - block: 'Panchayat Performance', - $default: 'Discrete Performance' - }, - current: 'Current musters', - delayed: 'Delayed musters' - }, - notifications : { - read : 'Read Notifications', - unread : 'Unread Notifications', - message: { - 1: { - $filter: 'role', - block: [' block made ',' payments to MGNREGA beneficiaries on ',' .'], - district: [' district made ',' payments to MGNREGA beneficiaries on ',' .'] - }, - 2: { - main: ['The average time from muster roll closure to bank processing for these transactions was ',' days, ',' the mandated maximum of 15 days.'], - comparison: ['greater than','equal to','less than'] - } - } - }, - browser_msg: 'The browser you are using is not supported. PayDash works best with Chrome, Firefox, or Internet Explorer 9+.', - messages: { - loading: 'Loading data...', - not_found: 'Page not found. Please contact the PayDash team if you need assistance.' - }, - time_selector: { - '1': 'All available dates', - '2': 'Past 60 days', - '3': 'Past 30 days' - }, - payment_steps: { - '1': 'Muster roll closure to muster roll entry', - '2': 'Muster roll entry to wage list generation', - '3': 'Wage list generation to wage list sent', - '4': 'Wage list sent to FTO generation', - '5': 'FTO generation to first signature', - '6': 'First signature to second signature', - '7': 'Second signature to processed by bank' - }, - payment_steps_labels: [ - 'Muster roll closure to muster roll entry', - 'Muster roll entry to wage list generation', - 'Wage list generation to wage list sent', - 'Wage list sent to FTO generation', - 'FTO generation to first signature', - 'First signature to second signature', - 'Second signature to processed by bank' - ], - compare_chart_labels: { - 'state': 'state average', - 'district': 'district average', - 'block': 'block average' - }, - y_axis_labels: 'Days to complete process', - total_trans: "Total transactions on", - performance: { - overview: { - chart_a: { - title: { - $filter: 'role', - district: 'District Performance', - block: 'Your Block\'s Performance', - $default: 'Overview Performance' - }, - description: { - $filter: 'role', - district: 'Average number of days to complete each step of the payment process in your district.', - block: 'Average number of days to complete each step of the payment process in your block.', - $default: 'Average number of days to complete each step of the payment process in your region.' - } - }, - chart_b: { - title: { - $filter: 'role', - district: 'Benchmarking Your Performance', - block: 'Benchmarking Your Performance', - $default: 'Benchmarking Your Performance' - }, - description: { - $filter: 'role', - district: 'Compare your performance with averages for your state.', - block: 'Compare your performance with averages for your district and state.', - $default: 'Compare your performance with averages for other regions.' - } - }, - tooltip: 'The chart at right shows the average number of days to complete each step of the payment process for payments that reached beneficiaries’ bank accounts on the given date. Therefore, only completed payments are displayed.', - }, - discrete: { - sub_heading: { - 1: 'Performance of', - 2: 'block/panchayat' - }, - subtitle: { - $filter: 'role', - block: 'The performance of your panchayat on average days to complete each step of the payment process.', - district: 'The performance of your blocks/panchayats on average days to complete each step of the payment process.', - $default: 'The performance of your regions on average days to complete each step of the payment process.' - }, - tooltip: 'The charts below show the average number of days to complete each step of the payment process for payments that reached beneficiaries’ bank accounts on the given date. Therefore, only completed payments are displayed. Your worst performing panchayats are shown first.', - ta_message: 'Your block has unmapped panchayats for the TA designation. As a result, we can\'t show you the performance of all the TA\'s in your block. Please visit the MGNREGA portal at nrega.nic.in to complete your TA mapping.', - grs_message: 'Your block has unmapped panchayats for the GRS designation. As a result, we can\'t show you the performance of all the GRS\'s in your block. Please visit the MGNREGA portal at nrega.nic.in to complete your GRS mapping.', - panchayat_chart_placeholder: 'Select a block or panchayat at left to view its payment performance', - grouping_selectors: { - no: 'No Grouping', - ta: 'Group by TA', - grs: 'Group by GRS' - }, - sidebar : { - total_trans: 'Total Transactions', - avg_days: 'Avg. days from muster roll closure to entry' - } - } - }, - musters: { - current: { - title: 'Musters Closing Today' - }, - delayed: { - title: 'Delayed Musters', - t_2: 'Attendance not filled (T+2)', - t_5: 'Measurement book not filled (T+5)', - t_6: 'Wagelist not sent (T+6)', - t_7: 'Pending for FTO first signature (T+7)', - t_8: 'Pending for FTO second signature (T+8)' - } - }, app: { $filter: 'role', block: { diff --git a/app/locales/hi/v1.js b/app/locales/hi/v1.js index 04cafb87..b10fe2f9 100644 --- a/app/locales/hi/v1.js +++ b/app/locales/hi/v1.js @@ -8,6 +8,12 @@ module.exports = { delayed: 'विलंबित मस्टर्स', days_to_payment: 'भुगतान के लिए दिन', description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' + }, + musters: { + $filter: 'role', + district: 'Muster translations', + block: 'Muster translations', + $default: 'Muster translations' } }, app: { From bc20f3ebe7aa0a7ffb3fd4c16c587b6e4a675263 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 26 Aug 2016 15:59:30 +0530 Subject: [PATCH 205/314] Cleanup web hindi translations from V2 --- app/locales/hi/v2.js | 163 ------------------------------------------- 1 file changed, 163 deletions(-) diff --git a/app/locales/hi/v2.js b/app/locales/hi/v2.js index bc386e8f..3afd0525 100644 --- a/app/locales/hi/v2.js +++ b/app/locales/hi/v2.js @@ -2,169 +2,6 @@ module.exports = { $meta: 'Hindi translation file', - profile: { - firstname: 'मूल नाम', - lastname: 'उपनाम', - profile: 'प्रोफ़ाइल', - account: 'अकाउंट', - work_email: 'औपचारिक e-mail', - mobile: 'मोबाइल नंबर', - personal_email: 'निजी e-mail', - lang : 'भाषा', - settings: 'सेट्टिंग्स', - logout: 'लौग आउट', - profile_settings: 'आपकी प्रोफ़ाइल सेट्टिंग्स', - email_settings: 'E-Mail सेट्टिंग्स', - primary_email_msg: 'आपके अकाउंट से संबंधित संदेशों और इंटरनेट-संबंधित प्रक्रियाओं के लिए आपके मुख्य e-mail ID का उपयोग किया जाएगा|', - save: 'अद्यतन (update)', - your_primary_email: 'आपका मुख्य e-mail ID', - change_pass: 'पासवर्ड बदलें', - old_pass: 'पुराना पासवर्ड ', - new_pass: 'नया पासवर्ड ', - pass_confirm:'नये पासवर्ड को सत्यापित करें', - forgot_pass: 'मैं अपना पासवर्ड भूल गयी/गया' - }, - navigation: { - overview: { - $filter: 'role', - district: 'ज़िला प्रदर्शन', - block: 'प्रखंड/जनपद प्रदर्शन', - $default: 'अवलोकन प्रदर्शन' - }, - discrete: { - $filter: 'role', - district: 'प्रखंड/जनपद प्रदर्शन', - block: 'पंचायत प्रदर्शन', - $default: 'अलहदा प्रदर्शन' - }, - current: 'वर्तमान मस्टर्स', - delayed: 'विलंबित मस्टर्स' - }, - notifications : { - read : 'पठित संदेश', - unread : 'अपठित संदेश', - message: { - 1: { - $filter: 'role', - block: [' प्रखंड/जनपद में ',' तारीख को ',' MGNREGA भुगतान हुए|'], - district: [' ज़िला में ',' तारीख को ',' MGNREGA भुगतान हुए|'] - }, - 2: { - main: ['औसतन, मस्टर रोल बंद होने से बैंक की कारवाई के समापन के बीच ',' दिन लगे, जो की सरकार द्वारा नियमित 15-दिन की सीमा ',' है|'], - comparison: ['से ज़्यादा','के बराबर','से कम'] - } - } - }, - browser_msg: 'आपका browser इस वेबसाइट के लिए अनुकूल नहीं है. PayDash चलाने के लिए Chrome, Firefox या Internet Explorer 9 या ऊंचे संस्करण का उपयोग करें|', - messages: { - loading: 'डाटा लोड हो रहा है...', - not_found: 'पृष्ठ नहीं मिला। Paydash टीम से संपर्क करें.' - }, - time_selector :{ - '1': 'सारी उपलब्ध तिथियाँ', - '2': 'पिछले 60 दिन', - '3': 'पिछले 30 दिन' - }, - payment_steps: { - '1': 'मस्टर रोल बंद से डाटा एंट्री का समय', - '2': 'डाटा एंट्री से वेज लिस्ट बनाने का समय', - '3': 'वेज लिस्ट बनाने से वेज लिस्ट भेजने का समय', - '4': 'वेज लिस्ट भेजने से FTO बनाने का समय', - '5': 'FTO बनाने से पहले हस्ताक्षर का समय', - '6': 'पहले हस्ताक्षर से दूसरे हस्ताक्षर का समय', - '7': 'दूसरे हस्ताक्षर से बैंक की कारवाई के समापन का समय' - }, - payment_steps_labels: [ - 'मस्टर रोल बंद से डाटा एंट्री का समय', - 'डाटा एंट्री से वेज लिस्ट बनाने का समय', - 'वेज लिस्ट बनाने से वेज लिस्ट भेजने का समय', - 'वेज लिस्ट भेजने से FTO बनाने का समय', - 'FTO बनाने से पहले हस्ताक्षर का समय', - 'पहले हस्ताक्षर से दूसरे हस्ताक्षर का समय', - 'दूसरे हस्ताक्षर से बैंक की कारवाई के समापन का समय' - ], - compare_chart_labels:{ - 'state': 'राज्य औसत', - 'district': 'ज़िला औसत', - 'block': 'प्रखंड/जनपद औसत' - }, - y_axis_labels: 'प्रक्रिया पूरी करने में लगे दिन', - total_trans :"तिथि : कुल भुगतानों की संख्या-", - performance: { - overview: { - chart_a: { - title: { - $filter: 'role', - district: 'आपके ज़िले का प्रदर्शन', - block: 'आपके प्रखंड/जनपद का प्रदर्शन', - $default: 'अवलोकन प्रदर्शन' - }, - description: { - $filter: 'role', - district: 'आपके ज़िले में मज़दूरी भुगतान के हर एक पड़ाव पर लगे औसत दिन', - block: 'आपके प्रखंड/जनपद में मज़दूरी भुगतान के हर एक पड़ाव पर लगे औसत दिन', - $default: 'आपके क्षेत्रों में मज़दूरी भुगतान के हर एक पड़ाव पर लगे औसत दिन' - } - }, - chart_b: { - title: { - $filter: 'role', - district: 'आपके प्रदर्शन की तुलना', - block: 'आपके प्रदर्शन की तुलना', - $default: 'आपके प्रदर्शन की तुलना' - }, - description: { - $filter: 'role', - district: 'अपने ज़िले के औसत प्रदर्शन की तुलना राज्य के औसत प्रदर्शन से करें', - block: 'अपने प्रखंड/जनपद के औसत प्रदर्शन की तुलना ज़िले और राज्य के औसत प्रदर्शन से करें ', - $default: 'अपने प्रखंड/जनपद के औसत प्रदर्शन की तुलना अन्य क्षेत्रों के औसत प्रदर्शन से करें' - } - }, - tooltip: 'यह ग्राफ़ MGNREGA मज़दूरी भुगतान में लगा औसत समय दिखाता है| वर्णित तिथियों पर हुए भुगतान में लगे समय को 7 पड़ावों में बाटा गया है| इसलिए, केवल पूरे हुए भुगतान का डाटा दिखाया जा रहा है|', - }, - discrete:{ - sub_heading: { - '1' : { - $filter: 'role', - block: 'आपके जनपद/प्रखंड की पंचायत', - district: 'आपके ज़िले में प्रखंड/पंचायत' - }, - '2' : 'का प्रदर्शन' - }, - subtitle: { - $filter: 'role', - block: 'आपकी पंचायतों में मज़दूरी भुगतान की प्रक्रिया के हर एक पड़ाव में लगा औसत समय', - district: 'आपके प्रखंडों/पंचायतों में मज़दूरी भुगतान की प्रक्रिया के हर एक पड़ाव में लगा औसत समय', - $default :'अपने क्षेत्रों में मज़दूरी भुगतान की प्रक्रिया के हर एक पड़ाव में लगा औसत समय' - }, - tooltip: 'यह ग्राफ़ MGNREGA मज़दूरी भुगतान में लगा औसत समय दिखाता है| वर्णित तिथियों पर हुए भुगतान में लगे समय को 7 पड़ावों में बाटा गया है| इसलिए, केवल पूरे हुए भुगतान का डाटा दिखाया जा रहा है|', - ta_message: 'आपके प्रखंड/जनपद में कुछ TAs/SEs/JEs और उनकी पंचायतों के नाम MGNREGA वेबसाइट पर अपडेट नहीं किए गये हैं| इस के परिणाम स्वरूप, हम आपको आपके प्रखंड/जनपद के सभी TAs/SEs/JEs के प्रदर्शन की जानकारी नहीं दे सकते| यह जानकारी पाने के लिए कृपया nrega.nic.in पर सभी TAs/SEs/JEs और उनकी पंचायतों के नाम भरें|', - grs_message: 'आपके प्रखंड/जनपद में कुछ GRSs और उनकी पंचायतों के नाम MGNREGA वेबसाइट पर अपडेट नहीं किए गये हैं| इस के परिणाम स्वरूप, हम आपको आपके प्रखंड/जनपद के सभी GRSs के प्रदर्शन की जानकारी नहीं दे सकते| यह जानकारी पाने के लिए कृपया nrega.nic.in पर सभी GRSs और उनकी पंचायतों के नाम भरें|', - panchayat_chart_placeholder: 'भुगतान के प्रदर्शन को देखने के लिए एक पंचायत या प्रखंड/जनपद का चयन करें ', - grouping_selectors: { - no: 'बिना कोई वर्गीकरण', - ta:'वर्ग: उप यंत्री', - grs: 'वर्ग: GRS' - }, - sidebar : { - total_trans: 'कुल भुगतान ', - avg_days: 'पंचायतों में मस्टर रोल बंद से डाटा एंट्री में लगा समय (औसत)' - } - } - }, - musters: { - current: { - title: 'आज बंद हो रहे मस्टर्स' - }, - delayed:{ - title: 'विलंबित मस्टर्स', - t_2: 'अटेंडेन्स नहीं भरी गयी (T+2)', - t_5: 'MB नहीं भरी गयी (T+5)', - t_6: 'वेज लिस्ट नहीं भेजी गयी (T+6)', - t_7: 'FTO पर पहला हस्ताक्षर नहीं हुआ (T+7)', - t_8: 'FTO पर दूसरा हस्ताक्षर नहीं हुआ (T+8)' - } - }, app: { $filter: 'role', block: { From 83cf31c80ccd6fc2e61514b1da33846a8403b3cd Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Sat, 27 Aug 2016 20:32:37 +0530 Subject: [PATCH 206/314] Update muster componenet for district version --- app/controllers/musters/musters.js | 6 +++ .../musters/{card.jsx => block-card.jsx} | 4 +- .../components/musters/district-card.jsx | 49 +++++++++++++++++++ assets/scripts/components/musters/group.jsx | 8 ++- assets/scripts/containers/musters.jsx | 5 +- 5 files changed, 67 insertions(+), 5 deletions(-) rename assets/scripts/components/musters/{card.jsx => block-card.jsx} (96%) create mode 100644 assets/scripts/components/musters/district-card.jsx diff --git a/app/controllers/musters/musters.js b/app/controllers/musters/musters.js index 40970aa3..15426c35 100644 --- a/app/controllers/musters/musters.js +++ b/app/controllers/musters/musters.js @@ -23,8 +23,14 @@ exports.getData = { var data; if (role === 'block') { data = MustersParser.block(rows); + data.config ={ + role: 'block' + }; } else if (role === 'district') { data = MustersParser.district(rows); + data.config ={ + role: 'district' + }; } data.translation = Translate('/web/musters', request.auth.credentials, null); diff --git a/assets/scripts/components/musters/card.jsx b/assets/scripts/components/musters/block-card.jsx similarity index 96% rename from assets/scripts/components/musters/card.jsx rename to assets/scripts/components/musters/block-card.jsx index 34ca691b..82db16d8 100644 --- a/assets/scripts/components/musters/card.jsx +++ b/assets/scripts/components/musters/block-card.jsx @@ -4,7 +4,7 @@ import React from 'react'; import Modal from '../global/modal.jsx'; import Table from './table.jsx'; -const Card = React.createClass({ +const BlockCard = React.createClass({ toggleModal() { const state = this.state.modalOpen; @@ -46,4 +46,4 @@ const Card = React.createClass({ }); -export default Card; +export default BlockCard; diff --git a/assets/scripts/components/musters/district-card.jsx b/assets/scripts/components/musters/district-card.jsx new file mode 100644 index 00000000..b95bf9e0 --- /dev/null +++ b/assets/scripts/components/musters/district-card.jsx @@ -0,0 +1,49 @@ +'use strict'; + +import React from 'react'; +import Modal from '../global/modal.jsx'; +import Table from './table.jsx'; + +const DistrictCard = React.createClass({ + + toggleModal() { + const state = this.state.modalOpen; + this.setState({ modalOpen: !state}); + }, + getInitialState: function(){ + return { + modalOpen: false + }; + }, + render: function(){ + return ( +
    +
    +
    +
    {this.props.data.name}
    +
    {this.props.data.designation}
    +
    {this.props.data.mobile}
    +
    +
    +
    +
    CURRENT
    +
    {this.props.data.current_total}
    +
    +
    +
    DELAYED
    +
    {this.props.data.delayed_total}
    +
    +
    + + +
    +
    +
    +
    +
    + ); + } +}); + + +export default DistrictCard; diff --git a/assets/scripts/components/musters/group.jsx b/assets/scripts/components/musters/group.jsx index 0eae61fc..a6b3ec83 100644 --- a/assets/scripts/components/musters/group.jsx +++ b/assets/scripts/components/musters/group.jsx @@ -21,6 +21,7 @@ const Group = React.createClass({ this.setState({cards: this.props.data.cards}); }, render: function(){ + var _this = this; return (
    @@ -30,7 +31,12 @@ const Group = React.createClass({
    { this.state.cards.map(function(data, i) { - return ; + if (_this.props.config.role === 'block') { + return ; + } else if (_this.props.config.role === 'district') { + return ; + } + }) }
    diff --git a/assets/scripts/containers/musters.jsx b/assets/scripts/containers/musters.jsx index bdb9ae5e..c291f821 100644 --- a/assets/scripts/containers/musters.jsx +++ b/assets/scripts/containers/musters.jsx @@ -14,7 +14,8 @@ const Musters = React.createClass({ .on('load', function(json) { _this.setState({ musters: json.musters, - translation: json.translation + translation: json.translation, + config: json.config }); }) .on('error', function(error) { @@ -37,7 +38,7 @@ const Musters = React.createClass({
    { _this.state.musters.map(function(data, i) { - return ; + return ; }) }
    From b793940a37607d3399df00df47910f6c28a7a4ce Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Sat, 27 Aug 2016 22:47:12 +0530 Subject: [PATCH 207/314] Update muster compoenents for district mode --- .../musters/{group.jsx => block-group.jsx} | 14 +++--- .../components/musters/district-card.jsx | 11 ++--- .../components/musters/district-group.jsx | 45 +++++++++++++++++++ assets/scripts/containers/musters.jsx | 18 ++++++-- 4 files changed, 68 insertions(+), 20 deletions(-) rename assets/scripts/components/musters/{group.jsx => block-group.jsx} (71%) create mode 100644 assets/scripts/components/musters/district-group.jsx diff --git a/assets/scripts/components/musters/group.jsx b/assets/scripts/components/musters/block-group.jsx similarity index 71% rename from assets/scripts/components/musters/group.jsx rename to assets/scripts/components/musters/block-group.jsx index a6b3ec83..6324799e 100644 --- a/assets/scripts/components/musters/group.jsx +++ b/assets/scripts/components/musters/block-group.jsx @@ -1,9 +1,9 @@ 'use strict'; import React from 'react'; -import Card from './card.jsx'; +import BlockCard from './block-card.jsx'; -const Group = React.createClass({ +const BlockGroup = React.createClass({ filterCards: function(event){ var updatedList = this.props.data.cards; @@ -22,6 +22,7 @@ const Group = React.createClass({ }, render: function(){ var _this = this; + return (
    @@ -31,12 +32,7 @@ const Group = React.createClass({
    { this.state.cards.map(function(data, i) { - if (_this.props.config.role === 'block') { - return ; - } else if (_this.props.config.role === 'district') { - return ; - } - + return ; }) }
    @@ -46,4 +42,4 @@ const Group = React.createClass({ }); -export default Group; +export default BlockGroup; diff --git a/assets/scripts/components/musters/district-card.jsx b/assets/scripts/components/musters/district-card.jsx index b95bf9e0..39dc11a8 100644 --- a/assets/scripts/components/musters/district-card.jsx +++ b/assets/scripts/components/musters/district-card.jsx @@ -20,9 +20,8 @@ const DistrictCard = React.createClass({
    -
    {this.props.data.name}
    -
    {this.props.data.designation}
    -
    {this.props.data.mobile}
    +
    {this.props.data.block_name}
    +
    {this.props.data.block_code}
    @@ -34,11 +33,7 @@ const DistrictCard = React.createClass({
    {this.props.data.delayed_total}
    - - -
    -
    -
    +
    ); diff --git a/assets/scripts/components/musters/district-group.jsx b/assets/scripts/components/musters/district-group.jsx new file mode 100644 index 00000000..916c4a57 --- /dev/null +++ b/assets/scripts/components/musters/district-group.jsx @@ -0,0 +1,45 @@ +'use strict'; + +import React from 'react'; +import DistrictCard from './district-card.jsx'; + +const BlockGroup = React.createClass({ + + filterCards: function(event){ + var updatedList = this.props.data.cards; + updatedList = updatedList.filter(function(item){ + return item.name.toLowerCase().search(event.target.value.toLowerCase()) !== -1; + }); + this.setState({cards: updatedList}); + }, + getInitialState: function(){ + return { + cards: [] + }; + }, + componentWillMount: function(){ + this.setState({cards: this.props.data.cards}); + }, + render: function(){ + var _this = this; + + return ( +
    +
    + +

    {this.props.data.region_name}

    +
    +
    + { + this.state.cards.map(function(data, i) { + return ; + }) + } +
    +
    + ); + } +}); + + +export default BlockGroup; diff --git a/assets/scripts/containers/musters.jsx b/assets/scripts/containers/musters.jsx index c291f821..ec94349f 100644 --- a/assets/scripts/containers/musters.jsx +++ b/assets/scripts/containers/musters.jsx @@ -1,7 +1,8 @@ 'use strict'; import React from 'react'; -import Group from '../components/musters/group.jsx'; +import BlockGroup from '../components/musters/block-group.jsx'; +import DistrictGroup from '../components/musters/district-group.jsx'; const D3= require('d3'); @@ -26,23 +27,34 @@ const Musters = React.createClass({ getInitialState: function() { return { - musters: [] + musters: [], + config: {} }; }, componentWillMount: function() { this.fetchMusters(); }, render: function(){ + var _this = this; + return (
    { _this.state.musters.map(function(data, i) { - return ; + if(_this.state.config.role ==='block'){ + return ; + } + else if(_this.state.config.role ==='district'){ + return ; + } }) }
    ); + + + } }); From b165a0f46bc4981cf772780e81fc426845af5289 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Sat, 27 Aug 2016 23:02:09 +0530 Subject: [PATCH 208/314] Add translations for musters page --- app/locales/en_US/v1.js | 7 +++---- app/locales/hi/v1.js | 29 ++++++++++++++--------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/app/locales/en_US/v1.js b/app/locales/en_US/v1.js index b605f03d..f918770d 100644 --- a/app/locales/en_US/v1.js +++ b/app/locales/en_US/v1.js @@ -10,10 +10,9 @@ module.exports = { description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' }, musters: { - $filter: 'role', - district: 'Muster translations', - block: 'Muster translations', - $default: 'Muster translations' + current: 'CURRENT', + delayed: 'DELAYED', + muster_details: 'MUSTER DETAILS' } }, app: { diff --git a/app/locales/hi/v1.js b/app/locales/hi/v1.js index b10fe2f9..4accf962 100644 --- a/app/locales/hi/v1.js +++ b/app/locales/hi/v1.js @@ -10,10 +10,9 @@ module.exports = { description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' }, musters: { - $filter: 'role', - district: 'Muster translations', - block: 'Muster translations', - $default: 'Muster translations' + current: 'CURRENT', + delayed: 'DELAYED', + muster_details: 'MUSTER DETAILS' } }, app: { @@ -39,14 +38,14 @@ module.exports = { chart: { days_to_complete_process: 'प्रक्रिया पूरी करने में लगे दिन', steps: { - 1:'मस्टर रोल बंद से डाटा एंट्री का समय', - 2:'डाटा एंट्री से वेज लिस्ट बनाने का समय', - 3:'वेज लिस्ट बनाने से वेज लिस्ट भेजने का समय', - 4:'वेज लिस्ट भेजने से FTO बनाने का समय', - 5:'FTO बनाने से पहले हस्ताक्षर का समय', - 6:'पहले हस्ताक्षर से दूसरे हस्ताक्षर का समय', - 7:'दूसरे हस्ताक्षर से बैंक की कारवाई के समापन का समय', - all:'पूरी प्रक्रिया के सारे पड़ाव', + 1: 'मस्टर रोल बंद से डाटा एंट्री का समय', + 2: 'डाटा एंट्री से वेज लिस्ट बनाने का समय', + 3: 'वेज लिस्ट बनाने से वेज लिस्ट भेजने का समय', + 4: 'वेज लिस्ट भेजने से FTO बनाने का समय', + 5: 'FTO बनाने से पहले हस्ताक्षर का समय', + 6: 'पहले हस्ताक्षर से दूसरे हस्ताक्षर का समय', + 7: 'दूसरे हस्ताक्षर से बैंक की कारवाई के समापन का समय', + all: 'पूरी प्रक्रिया के सारे पड़ाव', }, dates: { all_dates: 'सभी तारीखें', @@ -77,7 +76,7 @@ module.exports = { work_email: 'औपचारिक e-mail', mobile: 'मोबाइल नंबर', personal_email: 'निजी e-mail', - lang : 'भाषा', + lang: 'भाषा', settings: 'सेट्टिंग्स', logout: 'लौग आउट', profile_settings: 'आपकी प्रोफ़ाइल सेट्टिंग्स', @@ -88,7 +87,7 @@ module.exports = { change_pass: 'पासवर्ड बदलें', old_pass: 'पुराना पासवर्ड ', new_pass: 'नया पासवर्ड ', - pass_confirm:'नये पासवर्ड को सत्यापित करें', + pass_confirm: 'नये पासवर्ड को सत्यापित करें', forgot_pass: 'मैं अपना पासवर्ड भूल गयी/गया' }, messages: { @@ -100,7 +99,7 @@ module.exports = { logout: { connectivity: 'हमे खेद है कि आप log out करने में विफल रहे| कृपया अपने फ़ोन/कंप्यूटर की internet connectivity को जाँच लें |', warning: { - 'message':'क्या आप सचमुच Log Out करना चाहते हैं? PayDash का offline mode तभी तक उपलब्ध रहेगा जब तक आप logged in हैं |', + 'message': 'क्या आप सचमुच Log Out करना चाहते हैं? PayDash का offline mode तभी तक उपलब्ध रहेगा जब तक आप logged in हैं |', 'logout': 'Log out', 'cancel': 'Cancel' }, From 803c6bb021b3695df8df1f9833de3454e7e47f76 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Sat, 27 Aug 2016 23:13:38 +0530 Subject: [PATCH 209/314] Add translations for musters --- app/locales/en_US/v1.js | 10 +++++++++- app/locales/hi/v1.js | 14 +++++++++++--- assets/scripts/components/musters/block-card.jsx | 6 +++--- assets/scripts/components/musters/block-group.jsx | 2 +- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/app/locales/en_US/v1.js b/app/locales/en_US/v1.js index f918770d..804d3532 100644 --- a/app/locales/en_US/v1.js +++ b/app/locales/en_US/v1.js @@ -12,7 +12,15 @@ module.exports = { musters: { current: 'CURRENT', delayed: 'DELAYED', - muster_details: 'MUSTER DETAILS' + muster_details: 'MUSTER DETAILS', + current_musters: 'CURRENT MUSTERS', + delayed_musters: 'Delayed MUSTERS', + msr_no: 'MUSTER NO.', + panchayat_name :'PANCHAYAT NAME', + work_name : 'WORK NAME', + work_code: 'WORK CODE', + closure_date: 'CLOSURE DATE', + days_pending: 'DAYS PENDING' } }, app: { diff --git a/app/locales/hi/v1.js b/app/locales/hi/v1.js index 4accf962..a8d41f9a 100644 --- a/app/locales/hi/v1.js +++ b/app/locales/hi/v1.js @@ -10,9 +10,17 @@ module.exports = { description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' }, musters: { - current: 'CURRENT', - delayed: 'DELAYED', - muster_details: 'MUSTER DETAILS' + current: 'वर्तमान मस्टर्स', + delayed: 'विलंबित मस्टर्स', + muster_details: 'MUSTER DETAILS', + current_musters: 'विलंबित मस्टर्स', + delayed_musters: 'विलंबित मस्टर्स', + msr_no: 'MUSTER NO.', + panchayat_name :'PANCHAYAT NAME', + work_name : 'WORK NAME', + work_code: 'WORK CODE', + closure_date: 'CLOSURE DATE', + days_pending: 'DAYS PENDING' } }, app: { diff --git a/assets/scripts/components/musters/block-card.jsx b/assets/scripts/components/musters/block-card.jsx index 82db16d8..4ea1340b 100644 --- a/assets/scripts/components/musters/block-card.jsx +++ b/assets/scripts/components/musters/block-card.jsx @@ -26,15 +26,15 @@ const BlockCard = React.createClass({
    -
    CURRENT
    +
    {this.props.translation.current}
    {this.props.data.current_total}
    -
    DELAYED
    +
    {this.props.translation.delayed}
    {this.props.data.delayed_total}
    - +
    diff --git a/assets/scripts/components/musters/block-group.jsx b/assets/scripts/components/musters/block-group.jsx index 6324799e..b4aeb2c4 100644 --- a/assets/scripts/components/musters/block-group.jsx +++ b/assets/scripts/components/musters/block-group.jsx @@ -32,7 +32,7 @@ const BlockGroup = React.createClass({
    { this.state.cards.map(function(data, i) { - return ; + return ; }) }
    From 91e3da11a142276e476cad0f44ad809a69e67888 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Sun, 28 Aug 2016 02:38:41 +0530 Subject: [PATCH 210/314] Add hindi translation for musters --- app/locales/hi/v1.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/locales/hi/v1.js b/app/locales/hi/v1.js index a8d41f9a..50935a8e 100644 --- a/app/locales/hi/v1.js +++ b/app/locales/hi/v1.js @@ -12,14 +12,14 @@ module.exports = { musters: { current: 'वर्तमान मस्टर्स', delayed: 'विलंबित मस्टर्स', - muster_details: 'MUSTER DETAILS', + muster_details: 'मस्टर्स की विस्तार से जानकारी', current_musters: 'विलंबित मस्टर्स', delayed_musters: 'विलंबित मस्टर्स', msr_no: 'MUSTER NO.', panchayat_name :'PANCHAYAT NAME', - work_name : 'WORK NAME', - work_code: 'WORK CODE', - closure_date: 'CLOSURE DATE', + work_name : 'कार्य नाम', + work_code: 'कार्य कोड', + closure_date: 'मस्टर रोल बंद होने की तिथि', days_pending: 'DAYS PENDING' } }, From 0226f4e9d5fae99aaf69fcf359ff65f34aab6880 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Sun, 28 Aug 2016 02:58:21 +0530 Subject: [PATCH 211/314] Apply search for district musters --- assets/scripts/components/musters/district-group.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/scripts/components/musters/district-group.jsx b/assets/scripts/components/musters/district-group.jsx index 916c4a57..3c06368e 100644 --- a/assets/scripts/components/musters/district-group.jsx +++ b/assets/scripts/components/musters/district-group.jsx @@ -8,7 +8,7 @@ const BlockGroup = React.createClass({ filterCards: function(event){ var updatedList = this.props.data.cards; updatedList = updatedList.filter(function(item){ - return item.name.toLowerCase().search(event.target.value.toLowerCase()) !== -1; + return item.block_name.toLowerCase().search(event.target.value.toLowerCase()) !== -1; }); this.setState({cards: updatedList}); }, From b27ad2bf016763158c223acf1b2316b3a23c6578 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Sun, 28 Aug 2016 03:09:41 +0530 Subject: [PATCH 212/314] Apply translation logic to district muster components --- app/locales/en_US/v1.js | 1 + app/locales/hi/v1.js | 1 + assets/scripts/components/musters/district-card.jsx | 6 +++--- assets/scripts/components/musters/district-group.jsx | 9 +++++---- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/locales/en_US/v1.js b/app/locales/en_US/v1.js index 804d3532..fc8af398 100644 --- a/app/locales/en_US/v1.js +++ b/app/locales/en_US/v1.js @@ -13,6 +13,7 @@ module.exports = { current: 'CURRENT', delayed: 'DELAYED', muster_details: 'MUSTER DETAILS', + officer_details: 'OFFICER DETAILS', current_musters: 'CURRENT MUSTERS', delayed_musters: 'Delayed MUSTERS', msr_no: 'MUSTER NO.', diff --git a/app/locales/hi/v1.js b/app/locales/hi/v1.js index 50935a8e..30517def 100644 --- a/app/locales/hi/v1.js +++ b/app/locales/hi/v1.js @@ -13,6 +13,7 @@ module.exports = { current: 'वर्तमान मस्टर्स', delayed: 'विलंबित मस्टर्स', muster_details: 'मस्टर्स की विस्तार से जानकारी', + officer_details: 'OFFICER DETAILS', current_musters: 'विलंबित मस्टर्स', delayed_musters: 'विलंबित मस्टर्स', msr_no: 'MUSTER NO.', diff --git a/assets/scripts/components/musters/district-card.jsx b/assets/scripts/components/musters/district-card.jsx index 39dc11a8..ddc79c15 100644 --- a/assets/scripts/components/musters/district-card.jsx +++ b/assets/scripts/components/musters/district-card.jsx @@ -25,15 +25,15 @@ const DistrictCard = React.createClass({
    -
    CURRENT
    +
    {this.props.translation.current}
    {this.props.data.current_total}
    -
    DELAYED
    +
    {this.props.translation.delayed}
    {this.props.data.delayed_total}
    - +
    ); diff --git a/assets/scripts/components/musters/district-group.jsx b/assets/scripts/components/musters/district-group.jsx index 3c06368e..5cc622cf 100644 --- a/assets/scripts/components/musters/district-group.jsx +++ b/assets/scripts/components/musters/district-group.jsx @@ -21,18 +21,19 @@ const BlockGroup = React.createClass({ this.setState({cards: this.props.data.cards}); }, render: function(){ + var _this = this; return (
    - -

    {this.props.data.region_name}

    + +

    {_this.props.data.region_name}

    { - this.state.cards.map(function(data, i) { - return ; + _this.state.cards.map(function(data, i) { + return ; }) }
    From 3f148495f591962cbc79a09d937a194d13ed4d73 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Mon, 29 Aug 2016 11:46:25 -0400 Subject: [PATCH 213/314] update musters parser --- app/helpers/musters_parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/musters_parser.js b/app/helpers/musters_parser.js index ccc9142f..fe3ba636 100644 --- a/app/helpers/musters_parser.js +++ b/app/helpers/musters_parser.js @@ -102,7 +102,7 @@ exports.district = function(rows) { 't7_total': v[0].t7_total, 't7_avg': v[0].t7_avg, 't8_total': v[0].t8_total, - 't8_avg': v[0].t8_avg + 't8_avg': v[0].t8_avgw }; }) .entries(cardsResponse) From 6fc35e7b446343ba31dda7e3a2b67fffca352a68 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Mon, 29 Aug 2016 14:20:52 -0400 Subject: [PATCH 214/314] Make employee names uppercase in paydroid cards API --- app/helpers/paydroid_parser.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index 15be9c97..a52df7e0 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -232,7 +232,7 @@ exports.v2 = function(rows, role) { }) .rollup(function(v) { return { - 'name': v[0].name, + 'name': v[0].name.toUpperCase(), 'staff_id': v[0].staff_id, 'designation': Utils.getDesignation(v[0].task_assign, state_code), 'mobile': v[0].mobile_no, @@ -434,7 +434,7 @@ exports.v2 = function(rows, role) { 'officers': v.map(function(d) { return { officer_id: d.id, - name: d.id == null ? 'No Data' : d.firstname + ' ' + d.lastname, + name: d.id == null ? 'No Data' : d.firstname.toUpperCase() + ' ' + d.lastname.toUpperCase(), designation: d.designation, mobile: d.mobile }; From a3b91769634628daa8d0af92d5cf5a9b6cc6ce51 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Mon, 29 Aug 2016 15:43:27 -0400 Subject: [PATCH 215/314] Add user id to email subject line --- app/controllers/api/cards.js | 2 +- app/helpers/paydroid_parser.js | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/app/controllers/api/cards.js b/app/controllers/api/cards.js index 02582459..556b5bb0 100644 --- a/app/controllers/api/cards.js +++ b/app/controllers/api/cards.js @@ -38,7 +38,7 @@ exports.getData = { if (version === 1) { data = Parser.v1(rows); } else if (version === 2) { - data = Parser.v2(rows, role); + data = Parser.v2(rows, role, userId); } reply(data); diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index a52df7e0..eb713f4c 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -185,9 +185,9 @@ exports.v1 = function(rows) { }; -exports.v2 = function(rows, role) { +exports.v2 = function(rows, role, userId) { - function parse_block(rows) { + function parse_block(rows, userId) { var overviewResponse = D3.values(rows[0]); @@ -332,6 +332,8 @@ exports.v2 = function(rows, role) { return d.values; }); + var subjectLine = contactResponse[0].subject + '[' + userId + ']'; + var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'mrc_prc','tot_trn']; var data = { @@ -357,7 +359,7 @@ exports.v2 = function(rows, role) { 'contact': { 'phone': contactResponse[0].phone, 'email': contactResponse[0].email, - 'subject': contactResponse[0].subject + 'subject': subjectLine }, 'colors': { 'default': [ @@ -387,7 +389,7 @@ exports.v2 = function(rows, role) { return data; } - function parse_district(rows) { + function parse_district(rows, userId) { var overviewResponse = D3.values(rows[0]); @@ -523,6 +525,8 @@ exports.v2 = function(rows, role) { return d.values; }); + var subjectLine = contactResponse[0].subject + '[' + userId + ']'; + var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'mrc_prc','tot_trn']; var data = { @@ -548,7 +552,7 @@ exports.v2 = function(rows, role) { 'contact': { 'phone': contactResponse[0].phone, 'email': contactResponse[0].email, - 'subject': contactResponse[0].subject + 'subject': subjectLine }, 'colors': { 'default': [ @@ -580,11 +584,11 @@ exports.v2 = function(rows, role) { if (role==='block') { - var data = parse_block(rows); + var data = parse_block(rows, userId); } else if (role==='district') { - var data = parse_district(rows); + var data = parse_district(rows, userId); } From 2cf84b06bb6a8e8fedc667f6420d94edd718f6c5 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Mon, 29 Aug 2016 16:01:57 -0400 Subject: [PATCH 216/314] Add region names/codes to subject line for paydroid contact feature --- app/controllers/api/cards.js | 2 +- app/helpers/paydroid_parser.js | 21 +++++++++++++-------- app/helpers/queries.js | 6 ++++-- app/helpers/utils.js | 12 ++++++++++++ 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/app/controllers/api/cards.js b/app/controllers/api/cards.js index 556b5bb0..02582459 100644 --- a/app/controllers/api/cards.js +++ b/app/controllers/api/cards.js @@ -38,7 +38,7 @@ exports.getData = { if (version === 1) { data = Parser.v1(rows); } else if (version === 2) { - data = Parser.v2(rows, role, userId); + data = Parser.v2(rows, role); } reply(data); diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index eb713f4c..73127d78 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -185,9 +185,9 @@ exports.v1 = function(rows) { }; -exports.v2 = function(rows, role, userId) { +exports.v2 = function(rows, role) { - function parse_block(rows, userId) { + function parse_block(rows) { var overviewResponse = D3.values(rows[0]); @@ -203,6 +203,8 @@ exports.v2 = function(rows, role, userId) { var versionResponse = D3.values(rows[6]); + var regionsResponse = D3.values(rows[7]); + // Parse the overview response var overview = D3.nest() .key(function(d) { @@ -332,10 +334,10 @@ exports.v2 = function(rows, role, userId) { return d.values; }); - var subjectLine = contactResponse[0].subject + '[' + userId + ']'; - var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'mrc_prc','tot_trn']; + var subjectLine = Utils.buildSubject(contactResponse[0].subject, regionsResponse); + var data = { 'overview': overview, 'cards': cards, @@ -389,7 +391,7 @@ exports.v2 = function(rows, role, userId) { return data; } - function parse_district(rows, userId) { + function parse_district(rows) { var overviewResponse = D3.values(rows[0]); @@ -405,6 +407,8 @@ exports.v2 = function(rows, role, userId) { var versionResponse = D3.values(rows[6]); + var regionsResponse = D3.values(rows[7]); + // Parse the overview response var overview = D3.nest() .key(function(d) { @@ -525,7 +529,8 @@ exports.v2 = function(rows, role, userId) { return d.values; }); - var subjectLine = contactResponse[0].subject + '[' + userId + ']'; + + var subjectLine = Utils.buildSubject(contactResponse[0].subject, regionsResponse); var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'mrc_prc','tot_trn']; @@ -584,11 +589,11 @@ exports.v2 = function(rows, role, userId) { if (role==='block') { - var data = parse_block(rows, userId); + var data = parse_block(rows); } else if (role==='district') { - var data = parse_district(rows, userId); + var data = parse_district(rows); } diff --git a/app/helpers/queries.js b/app/helpers/queries.js index b81f1d6e..25f610ba 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -47,7 +47,8 @@ exports.paydroid = function(USER_ID,ROLE,VERSION) { "SELECT block_code, panchayat_code, panchayat_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc, ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), panchayat_code ORDER BY panchayat_code, date;" + "SELECT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + "SELECT * FROM contact;" + - "SELECT * FROM paydroid_version;"; + "SELECT * FROM paydroid_version;" + + "SELECT * FROM user_regions WHERE user_id="+USER_ID+";"; } else if (ROLE=='district') { return "SELECT a.region_code as district_code, a.region_name as district_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, IFNULL(d.days_to_payment,'No Data') AS days_to_payment FROM (SELECT region_code, region_name FROM user_regions WHERE user_id='"+USER_ID+"') a LEFT JOIN (SELECT count(*) AS current_total, b.district_code AS region_code FROM current_musters a RIGHT JOIN (SELECT district_code, block_code from blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code GROUP BY region_code ) b ON a.region_code = b.region_code LEFT JOIN (SELECT count(*) AS delayed_total, b.district_code AS region_code FROM delayed_musters a RIGHT JOIN (SELECT district_code, block_code from blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code GROUP BY region_code ) c ON a.region_code = c.region_code LEFT JOIN (SELECT ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1) AS days_to_payment, district_code AS region_code FROM district_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY region_code) d ON a.region_code = d.region_code;" + "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, IFNULL(b.days_to_payment,'No Data') AS days_to_payment, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;" + @@ -55,7 +56,8 @@ exports.paydroid = function(USER_ID,ROLE,VERSION) { "SELECT district_code, block_code, block_name, SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc, ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;" + "SELECT state_code FROM districts WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + "SELECT * FROM contact;" + - "SELECT * FROM paydroid_version;"; + "SELECT * FROM paydroid_version;" + + "SELECT * FROM user_regions WHERE user_id="+USER_ID+";"; } } }; diff --git a/app/helpers/utils.js b/app/helpers/utils.js index 777d8772..af05b9e1 100644 --- a/app/helpers/utils.js +++ b/app/helpers/utils.js @@ -55,3 +55,15 @@ exports.getDesignation = function(task_assign, state_code) { return task_assign; } }; + +exports.buildSubject = function(subjectStub, regionsResponse) { + var subjectLine = subjectStub + ' ['; + for (var i=0; i0) { + subjectLine += '/'; + } + subjectLine += regionsResponse[i].region_name + ' (' + regionsResponse[i].region_code + ')'; + } + subjectLine += ']'; + return subjectLine; +} From b335d1900aacd55e9d19bac250374f28222becca Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Mon, 29 Aug 2016 16:50:31 -0400 Subject: [PATCH 217/314] Add translation keys --- app/locales/en_US/v2.js | 16 +++++++++++----- app/locales/hi/v2.js | 14 ++++++++++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/app/locales/en_US/v2.js b/app/locales/en_US/v2.js index 7aab5a42..aa644f59 100644 --- a/app/locales/en_US/v2.js +++ b/app/locales/en_US/v2.js @@ -87,8 +87,8 @@ module.exports = { }, search: 'Search for TA/GRS...', sort: { - current_total: 'Current total', - delayed_total: 'Delayed total', + current_total: 'Musters closing today', + delayed_total: 'Delayed musters', name: 'Name', designation: 'Designation' }, @@ -107,10 +107,13 @@ module.exports = { }, general: 'Unable to log out of PayDash. Please contact the PayDash team if this issue persists.' }, + profile_success: 'Profile successfully updated.', + profile_error: 'Unable to update profile. Please contact the PayDash team if this issue persists.', password_success: 'Password changed successfully. Please login with new password.', password_wrong_old: 'Old password is incorrect. Please contact the PayDash team if you require assistance.', password_new_nomatch: 'New password does not match.', password_tooshort: 'Your new password must be at least 6 characters long.', + password_network_error: 'Unable to change password. Please try again when you have network connectivity.', password_empty: 'Password cannot be empty', requesting_change: 'Requesting password change...' }, @@ -209,9 +212,9 @@ module.exports = { }, search: 'Search for Block or Officer Name...', sort: { - current_total: 'Current total', - delayed_total: 'Delayed total', - days_to_payment: 'Avg. days to payment', + current_total: 'Musters closing today', + delayed_total: 'Delayed musters', + days_to_payment: 'Avg. days to payment in last 3 months', block_name: 'Block name', ceo_name: 'Block CEO name' }, @@ -230,10 +233,13 @@ module.exports = { }, general: 'Unable to log out of PayDash. Please contact the PayDash team if this issue persists.' }, + profile_success: 'Profile successfully updated.', + profile_error: 'Unable to update profile. Please contact the PayDash team if this issue persists.', password_success: 'Password changed successfully. Please login with new password.', password_wrong_old: 'Old password is incorrect. Please contact the PayDash team if you require assistance.', password_new_nomatch: 'New password does not match.', password_tooshort: 'Your new password must be at least 6 characters long.', + password_network_error: 'Unable to change password. Please try again when you have network connectivity.', password_empty: 'Password cannot be empty', requesting_change: 'Requesting password change...' }, diff --git a/app/locales/hi/v2.js b/app/locales/hi/v2.js index 3afd0525..944f5f2e 100644 --- a/app/locales/hi/v2.js +++ b/app/locales/hi/v2.js @@ -87,8 +87,8 @@ module.exports = { }, search: 'Search for TA/GRS...', sort: { - current_total: 'Current total', - delayed_total: 'Delayed total', + current_total: 'आज बंद हो रहे मस्टर्स', + delayed_total: 'विलंबित मस्टर्स', name: 'Name', designation: 'Designation' }, @@ -107,10 +107,13 @@ module.exports = { }, general: 'हमे खेद है कि आप log out करने में विफल रहे| यदि यह समस्या कायम रहती है तो PayDash दल से संपर्क करें|' }, + profile_success: 'Profile successfully updated.', + profile_error: 'Unable to update profile. Please contact the PayDash team if this problem persists.', password_success: 'पासवर्ड सफलतापूर्वक बदला जा चुका है| कृपया नये पासवर्ड का उपयोग कर लॉग इन करें|', password_wrong_old: 'पुराना पासवर्ड ग़लत है| सहयता के लिए PayDash दल से संपर्क करें|', password_new_nomatch: 'नया पासवर्ड मेल नही ख़ाता|', password_tooshort: 'आपके नये पासवर्ड की लंबाई कम से कम 6 अक्षर होनी चाहिए|', + password_network_error: 'Unable to change password. Please try again when you have network connectivity.', password_empty: 'Password cannot be empty', requesting_change: 'Requesting password change...' }, @@ -209,9 +212,9 @@ module.exports = { }, search: 'Search for Block or Officer Name...', sort: { - current_total: 'Current total', + current_total: 'आज बंद हो रहे मस्टर्स', delayed_total: 'Delayed total', - days_to_payment: 'Avg. days to payment', + days_to_payment: 'पिछले 3 महीनों में किए गये हर भुगतान में लगे औसत दिन', block_name: 'Block name', ceo_name: 'Block CEO name' }, @@ -230,10 +233,13 @@ module.exports = { }, general: 'हमे खेद है कि आप log out करने में विफल रहे| यदि यह समस्या कायम रहती है तो PayDash दल से संपर्क करें|' }, + profile_success: 'Profile successfully updated.', + profile_error: 'Unable to update profile. Please contact the PayDash team if this problem persists.', password_success: 'पासवर्ड सफलतापूर्वक बदला जा चुका है| कृपया नये पासवर्ड का उपयोग कर लॉग इन करें|', password_wrong_old: 'पुराना पासवर्ड ग़लत है| सहयता के लिए PayDash दल से संपर्क करें|', password_new_nomatch: 'नया पासवर्ड मेल नही ख़ाता|', password_tooshort: 'आपके नये पासवर्ड की लंबाई कम से कम 6 अक्षर होनी चाहिए|', + password_network_error: 'Unable to change password. Please try again when you have network connectivity.', password_empty: 'Password cannot be empty', requesting_change: 'Requesting password change...' }, From 26a901f0e88a7632ecb9f21077ece872055b748d Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Tue, 30 Aug 2016 13:52:42 -0400 Subject: [PATCH 218/314] Update sorting of cards in both web and mobile API --- app/helpers/musters_parser.js | 23 +++++++++++++++++++++++ app/helpers/paydroid_parser.js | 8 ++++++++ app/helpers/queries.js | 4 ++-- app/locales/en_US/v1.js | 2 +- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/app/helpers/musters_parser.js b/app/helpers/musters_parser.js index fe3ba636..8e16123e 100644 --- a/app/helpers/musters_parser.js +++ b/app/helpers/musters_parser.js @@ -57,6 +57,25 @@ exports.block = function(rows) { 'region_name': d.key.substr(7), 'cards': d.values.map(function(e) { return e.values; + }).sort(function (a, b){ + var aActive = a.current_total + a.delayed_total > 0 ? 1 : 0; + var bActive = b.current_total + b.delayed_total > 0 ? 1 : 0; + var aUnmapped = a.name === 'Unmapped' ? 1 : 0; + var bUnmapped = b.name === 'Unmapped' ? 1 : 0; + + // ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, name;" + + if (aActive < bActive) return 1; + if (aActive > bActive) return -1; + if (aUnmapped < bUnmapped) return -1; + if (aUnmapped > bUnmapped) return 1; + if (a.delayed_total < b.delayed_total) return 1; + if (a.delayed_total > b.delayed_total) return -1; + if (a.current_total < b.current_total) return 1; + if (a.current_total > b.current_total) return -1; + if (a.name < b.name) return -1; + if (a.name > b.name) return 1; + return 0; }) }; }); @@ -113,6 +132,10 @@ exports.district = function(rows) { 'region_name': d.key.substr(4), 'cards': d.values.map(function(e) { return e.values; + }).sort(function (a, b){ + if (a.block_name.toLowerCase() < b.block_name.toLowerCase()) return -1; + if (a.block_name.toLowerCase() > b.block_name.toLowerCase()) return 1; + return 0; }) }; }); diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index 73127d78..5530c9cc 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -445,6 +445,7 @@ exports.v2 = function(rows, role) { mobile: d.mobile }; }), + 'district_name': v[0].district_name, 'block_code': v[0].block_code, 'block_name': v[0].block_name, 'current_total': v[0].current_total, @@ -465,6 +466,13 @@ exports.v2 = function(rows, role) { .entries(cardsResponse) .map(function(d) { return d.values; + }) + .sort(function (a, b){ + if (a.district_name.toLowerCase() < b.district_name.toLowerCase()) return -1; + if (a.district_name.toLowerCase() > b.district_name.toLowerCase()) return 1; + if (a.block_name.toLowerCase() < b.block_name.toLowerCase()) return -1; + if (a.block_name.toLowerCase() > b.block_name.toLowerCase()) return 1; + return 0; }); // Nest the district response diff --git a/app/helpers/queries.js b/app/helpers/queries.js index 25f610ba..66b1f9d5 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -10,7 +10,7 @@ exports.overview = function(USER_ID, ROLE) { exports.cards = function(USER_ID, ROLE) { if (ROLE === 'block') { - return "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) WHERE a.staff_id IS NOT NULL OR (a.staff_id IS NULL AND (c.current_total>0 OR d.delayed_total>0)) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + + return "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) WHERE a.staff_id IS NOT NULL OR (a.staff_id IS NULL AND (c.current_total>0 OR d.delayed_total>0)) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, name;" + "SELECT DISTINCT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"');"; } else if (ROLE === 'district') { return "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, b.days_to_payment, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;"; @@ -42,7 +42,7 @@ exports.paydroid = function(USER_ID,ROLE,VERSION) { } else if (VERSION===2) { if (ROLE==='block') { return "SELECT a.region_code as block_code, a.region_name as block_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, IFNULL(d.days_to_payment,'No Data') AS days_to_payment FROM (SELECT region_code, region_name FROM user_regions WHERE user_id='"+USER_ID+"') a LEFT JOIN (SELECT count(*) AS current_total, block_code AS region_code FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY region_code) b ON a.region_code = b.region_code LEFT JOIN (SELECT count(*) AS delayed_total, block_code AS region_code FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY region_code) c ON a.region_code = c.region_code LEFT JOIN (SELECT ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1) AS days_to_payment, block_code AS region_code FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY region_code) d ON a.region_code = d.region_code;" + - "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) WHERE a.staff_id IS NOT NULL OR (a.staff_id IS NULL AND (c.current_total>0 OR d.delayed_total>0)) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + + "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) WHERE a.staff_id IS NOT NULL OR (a.staff_id IS NULL AND (c.current_total>0 OR d.delayed_total>0)) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, name;" + "SELECT block_code, block_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc, ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;" + "SELECT block_code, panchayat_code, panchayat_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc, ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), panchayat_code ORDER BY panchayat_code, date;" + "SELECT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + diff --git a/app/locales/en_US/v1.js b/app/locales/en_US/v1.js index fc8af398..f51a4b01 100644 --- a/app/locales/en_US/v1.js +++ b/app/locales/en_US/v1.js @@ -4,7 +4,7 @@ module.exports = { $meta: 'English translation file', web: { overview: { - current: 'CUREENT', + current: 'CURRENT', delayed: 'DELAYED', days_to_payment: 'DAYS TO PAYMENT', description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' From 1ae352836da8ffc0511e71d08e95d8c79dfbea0d Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Tue, 30 Aug 2016 14:21:50 -0400 Subject: [PATCH 219/314] Move all card sorting from SQL to JS --- app/helpers/paydroid_parser.js | 20 ++++++++++++++++++++ app/helpers/queries.js | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index 5530c9cc..03c44954 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -269,6 +269,26 @@ exports.v2 = function(rows, role) { .entries(cardsResponse) .map(function(d) { return d.values; + }) + .sort(function (a, b){ + var aActive = a.current_total + a.delayed_total > 0 ? 1 : 0; + var bActive = b.current_total + b.delayed_total > 0 ? 1 : 0; + var aUnmapped = a.name.toLowerCase() === 'unmapped' ? 1 : 0; + var bUnmapped = b.name.toLowerCase() === 'unmapped' ? 1 : 0; + + // ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, name;" + + if (aActive < bActive) return 1; + if (aActive > bActive) return -1; + if (aUnmapped < bUnmapped) return -1; + if (aUnmapped > bUnmapped) return 1; + if (a.delayed_total < b.delayed_total) return 1; + if (a.delayed_total > b.delayed_total) return -1; + if (a.current_total < b.current_total) return 1; + if (a.current_total > b.current_total) return -1; + if (a.name < b.name) return -1; + if (a.name > b.name) return 1; + return 0; }); diff --git a/app/helpers/queries.js b/app/helpers/queries.js index 66b1f9d5..faff38b1 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -10,7 +10,7 @@ exports.overview = function(USER_ID, ROLE) { exports.cards = function(USER_ID, ROLE) { if (ROLE === 'block') { - return "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) WHERE a.staff_id IS NOT NULL OR (a.staff_id IS NULL AND (c.current_total>0 OR d.delayed_total>0)) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, name;" + + return "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) WHERE a.staff_id IS NOT NULL OR (a.staff_id IS NULL AND (c.current_total>0 OR d.delayed_total>0));" + "SELECT DISTINCT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"');"; } else if (ROLE === 'district') { return "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, b.days_to_payment, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;"; @@ -42,7 +42,7 @@ exports.paydroid = function(USER_ID,ROLE,VERSION) { } else if (VERSION===2) { if (ROLE==='block') { return "SELECT a.region_code as block_code, a.region_name as block_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, IFNULL(d.days_to_payment,'No Data') AS days_to_payment FROM (SELECT region_code, region_name FROM user_regions WHERE user_id='"+USER_ID+"') a LEFT JOIN (SELECT count(*) AS current_total, block_code AS region_code FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY region_code) b ON a.region_code = b.region_code LEFT JOIN (SELECT count(*) AS delayed_total, block_code AS region_code FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY region_code) c ON a.region_code = c.region_code LEFT JOIN (SELECT ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1) AS days_to_payment, block_code AS region_code FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY region_code) d ON a.region_code = d.region_code;" + - "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) WHERE a.staff_id IS NOT NULL OR (a.staff_id IS NULL AND (c.current_total>0 OR d.delayed_total>0)) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, name;" + + "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) WHERE a.staff_id IS NOT NULL OR (a.staff_id IS NULL AND (c.current_total>0 OR d.delayed_total>0));" + "SELECT block_code, block_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc, ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;" + "SELECT block_code, panchayat_code, panchayat_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc, ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), panchayat_code ORDER BY panchayat_code, date;" + "SELECT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + From d6565fa8b68b5277f8eb89826b0b9c0c4695e71d Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Tue, 30 Aug 2016 16:11:48 -0400 Subject: [PATCH 220/314] Update district queries to pull from block_officers table. Sort officers on district cards --- app/helpers/musters_parser.js | 6 +++++- app/helpers/paydroid_parser.js | 7 +++++-- app/helpers/queries.js | 4 ++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/helpers/musters_parser.js b/app/helpers/musters_parser.js index 8e16123e..e276ba65 100644 --- a/app/helpers/musters_parser.js +++ b/app/helpers/musters_parser.js @@ -103,10 +103,14 @@ exports.district = function(rows) { return { 'officers': v.map(function(d) { return { - name: d.id === null ? 'No Data' : d.firstname + ' ' + d.lastname, + officer_id: d.block_code + '_' + d.designation_id, + name: d.firstname == null && d.lastname == null ? 'No Data' : d.firstname.toUpperCase() + ' ' + d.lastname.toUpperCase(), designation: d.designation, + designation_id: d.designation_id, mobile: d.mobile }; + }).sort(function(a,b) { + return a.designation_id - b.designation_id; }), 'block_code': v[0].block_code, 'block_name': v[0].block_name, diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index 03c44954..36f05318 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -459,11 +459,14 @@ exports.v2 = function(rows, role) { return { 'officers': v.map(function(d) { return { - officer_id: d.id, - name: d.id == null ? 'No Data' : d.firstname.toUpperCase() + ' ' + d.lastname.toUpperCase(), + officer_id: d.block_code + '_' + d.designation_id, + name: d.firstname == null && d.lastname == null ? 'No Data' : d.firstname.toUpperCase() + ' ' + d.lastname.toUpperCase(), designation: d.designation, + designation_id: d.designation_id, mobile: d.mobile }; + }).sort(function(a,b) { + return a.designation_id - b.designation_id; }), 'district_name': v[0].district_name, 'block_code': v[0].block_code, diff --git a/app/helpers/queries.js b/app/helpers/queries.js index faff38b1..bc99d55e 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -13,7 +13,7 @@ exports.cards = function(USER_ID, ROLE) { return "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) WHERE a.staff_id IS NOT NULL OR (a.staff_id IS NULL AND (c.current_total>0 OR d.delayed_total>0));" + "SELECT DISTINCT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"');"; } else if (ROLE === 'district') { - return "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, b.days_to_payment, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;"; + return "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, j.designation_id, IFNULL(j.mobile,'No Data') AS mobile, b.days_to_payment, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT a.block_code, a.firstname, a.lastname, a.designation, a.designation_id, a.mobile FROM block_officers a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code) j ON a.block_code=j.block_code;"; } }; @@ -51,7 +51,7 @@ exports.paydroid = function(USER_ID,ROLE,VERSION) { "SELECT * FROM user_regions WHERE user_id="+USER_ID+";"; } else if (ROLE=='district') { return "SELECT a.region_code as district_code, a.region_name as district_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, IFNULL(d.days_to_payment,'No Data') AS days_to_payment FROM (SELECT region_code, region_name FROM user_regions WHERE user_id='"+USER_ID+"') a LEFT JOIN (SELECT count(*) AS current_total, b.district_code AS region_code FROM current_musters a RIGHT JOIN (SELECT district_code, block_code from blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code GROUP BY region_code ) b ON a.region_code = b.region_code LEFT JOIN (SELECT count(*) AS delayed_total, b.district_code AS region_code FROM delayed_musters a RIGHT JOIN (SELECT district_code, block_code from blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code GROUP BY region_code ) c ON a.region_code = c.region_code LEFT JOIN (SELECT ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1) AS days_to_payment, district_code AS region_code FROM district_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY region_code) d ON a.region_code = d.region_code;" + - "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, IFNULL(b.days_to_payment,'No Data') AS days_to_payment, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;" + + "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, j.designation_id, IFNULL(j.mobile,'No Data') AS mobile, IFNULL(b.days_to_payment,'No Data') AS days_to_payment, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT a.block_code, a.firstname, a.lastname, a.designation, a.designation_id, a.mobile FROM block_officers a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code) j ON a.block_code=j.block_code;" + "SELECT district_code, district_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc,ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM district_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), district_code ORDER BY district_code, date;" + "SELECT district_code, block_code, block_name, SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc, ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;" + "SELECT state_code FROM districts WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + From 681fc1f2b01562b957b690d373fecd28e3d786d3 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Tue, 30 Aug 2016 17:12:16 -0400 Subject: [PATCH 221/314] Update paydroid colors --- app/helpers/paydroid_parser.js | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index 36f05318..b09590d0 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -592,14 +592,22 @@ exports.v2 = function(rows, role) { }, 'colors': { 'default': [ - '#ffd300', - '#18ff00', - '#f57070', - '#f8b128', - '#f7f7f7', - '#F22613', - '#FDE3A7', - '#f57070' + // '#ffd300', + // '#18ff00', + // '#f57070', + // '#f8b128', + // '#f7f7f7', + // '#F22613', + // '#FDE3A7', + // '#f57070' + + '#F15854', + '#B2912F', + '#F17CB0', + '#60BD68', + '#FAA43A', + '#5DA5DA', + '#B276B2' ], 'colorblind': [ '#ffd300', From c1f1b49e2d2997b3a0a284554b41274d866552fa Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Wed, 31 Aug 2016 22:45:21 +0530 Subject: [PATCH 222/314] Add hindi text --- assets/scripts/components/musters/block-card.jsx | 4 ++-- assets/scripts/components/musters/table.jsx | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/assets/scripts/components/musters/block-card.jsx b/assets/scripts/components/musters/block-card.jsx index 4ea1340b..6037dd46 100644 --- a/assets/scripts/components/musters/block-card.jsx +++ b/assets/scripts/components/musters/block-card.jsx @@ -36,8 +36,8 @@ const BlockCard = React.createClass({
    -
    -
    +
    +
    diff --git a/assets/scripts/components/musters/table.jsx b/assets/scripts/components/musters/table.jsx index 985b95ad..c4f932cb 100644 --- a/assets/scripts/components/musters/table.jsx +++ b/assets/scripts/components/musters/table.jsx @@ -5,22 +5,24 @@ import React from 'react'; const Table = React.createClass({ render: function(){ + + var _this = this; return (
    -

    {this.props.title}

    +

    {_this.props.title}

    { - this.props.data.length > 0 && Object.keys(this.props.data[0]).map(function(key){ - return ; + _this.props.data.length > 0 && Object.keys(_this.props.data[0]).map(function(key){ + return ; }) } { - this.props.data.map(function(data, i) { + _this.props.data.map(function(data, i) { return ( { From a36d200f443a673805538290333e869e51125ea4 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Wed, 31 Aug 2016 23:33:54 +0530 Subject: [PATCH 223/314] Add muster details on card --- .../scripts/components/musters/district-card.jsx | 14 ++++++++++++++ assets/styles/views/musters.scss | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/assets/scripts/components/musters/district-card.jsx b/assets/scripts/components/musters/district-card.jsx index ddc79c15..6cdd5a33 100644 --- a/assets/scripts/components/musters/district-card.jsx +++ b/assets/scripts/components/musters/district-card.jsx @@ -33,6 +33,20 @@ const DistrictCard = React.createClass({
    {this.props.data.delayed_total}
    +

    OFFICERS

    + { + this.props.data.officers.map(function(officer, i) { + return ( +
    +
    {officer.name}
    +
    + {officer.designation} + {officer.mobile} +
    +
    + ); + }) + } diff --git a/assets/styles/views/musters.scss b/assets/styles/views/musters.scss index 11a93cb7..de7bcf10 100644 --- a/assets/styles/views/musters.scss +++ b/assets/styles/views/musters.scss @@ -39,3 +39,12 @@ font-size: $fontSize-smaller; color: $color-grey-light; } +.card-officer{ + text-align: left; + color: $color-grey-dark; + margin-bottom: 20px; +} +.card-officer-sub{ + font-size: $fontSize-small; + color: $color-grey-light; +} From a63d2fb673334ffecfcae41581179a56f63b259d Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Wed, 31 Aug 2016 23:41:20 +0530 Subject: [PATCH 224/314] Design officer details on district card --- app/locales/en_US/v1.js | 2 +- app/locales/hi/v1.js | 3 +-- assets/scripts/components/musters/district-card.jsx | 4 ++-- assets/styles/views/musters.scss | 11 +++++++++-- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/app/locales/en_US/v1.js b/app/locales/en_US/v1.js index f51a4b01..ac2a16cc 100644 --- a/app/locales/en_US/v1.js +++ b/app/locales/en_US/v1.js @@ -13,7 +13,7 @@ module.exports = { current: 'CURRENT', delayed: 'DELAYED', muster_details: 'MUSTER DETAILS', - officer_details: 'OFFICER DETAILS', + officers: 'OFFICERS', current_musters: 'CURRENT MUSTERS', delayed_musters: 'Delayed MUSTERS', msr_no: 'MUSTER NO.', diff --git a/app/locales/hi/v1.js b/app/locales/hi/v1.js index 30517def..3a6824a6 100644 --- a/app/locales/hi/v1.js +++ b/app/locales/hi/v1.js @@ -13,8 +13,7 @@ module.exports = { current: 'वर्तमान मस्टर्स', delayed: 'विलंबित मस्टर्स', muster_details: 'मस्टर्स की विस्तार से जानकारी', - officer_details: 'OFFICER DETAILS', - current_musters: 'विलंबित मस्टर्स', + officers: 'OFFICERS', delayed_musters: 'विलंबित मस्टर्स', msr_no: 'MUSTER NO.', panchayat_name :'PANCHAYAT NAME', diff --git a/assets/scripts/components/musters/district-card.jsx b/assets/scripts/components/musters/district-card.jsx index 6cdd5a33..218f8efd 100644 --- a/assets/scripts/components/musters/district-card.jsx +++ b/assets/scripts/components/musters/district-card.jsx @@ -33,7 +33,7 @@ const DistrictCard = React.createClass({
    {this.props.data.delayed_total}
    -

    OFFICERS

    +

    {this.props.translation.officers}

    { this.props.data.officers.map(function(officer, i) { return ( @@ -47,7 +47,7 @@ const DistrictCard = React.createClass({ ); }) } - + ); diff --git a/assets/styles/views/musters.scss b/assets/styles/views/musters.scss index de7bcf10..8f54496a 100644 --- a/assets/styles/views/musters.scss +++ b/assets/styles/views/musters.scss @@ -41,10 +41,17 @@ } .card-officer{ text-align: left; - color: $color-grey-dark; + color: $color-grey-light; margin-bottom: 20px; } +.card-officer-title{ + text-align:left; + font-weight: 400; +} .card-officer-sub{ font-size: $fontSize-small; - color: $color-grey-light; + color: $color-grey-lighter; +} +.card .card-officer:last-child{ + padding-botttom: 40px; } From 92cd0475ea0993f1af09a9a663374a4f85b46531 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Wed, 31 Aug 2016 23:42:35 +0530 Subject: [PATCH 225/314] Add modal on district card --- assets/scripts/components/musters/district-card.jsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/assets/scripts/components/musters/district-card.jsx b/assets/scripts/components/musters/district-card.jsx index 218f8efd..acbefc4a 100644 --- a/assets/scripts/components/musters/district-card.jsx +++ b/assets/scripts/components/musters/district-card.jsx @@ -47,7 +47,10 @@ const DistrictCard = React.createClass({ ); }) } - + + + + ); From 04594fd4a9b75950127056365d14ce17a32b3ba4 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 1 Sep 2016 00:04:44 +0530 Subject: [PATCH 226/314] Add district card muster details --- .../components/musters/district-card.jsx | 34 ++++++++++++++++++- assets/styles/views/musters.scss | 5 ++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/assets/scripts/components/musters/district-card.jsx b/assets/scripts/components/musters/district-card.jsx index acbefc4a..dcd5d1b4 100644 --- a/assets/scripts/components/musters/district-card.jsx +++ b/assets/scripts/components/musters/district-card.jsx @@ -49,7 +49,39 @@ const DistrictCard = React.createClass({ } - +

    MUISTER DETAILS

    +
    {key}{_this.props.translation[key]}
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    StepTotalAverage
    T+2{this.props.data.t2_total}{this.props.data.t2_avg}
    T+5{this.props.data.t5_total}{this.props.data.t5_avg}
    T+6{this.props.data.t6_total}{this.props.data.t6_avg}
    T+7{this.props.data.t7_total}{this.props.data.t7_avg}
    T+8{this.props.data.t8_total}{this.props.data.t8_avg}
    diff --git a/assets/styles/views/musters.scss b/assets/styles/views/musters.scss index 8f54496a..05bd9c9d 100644 --- a/assets/styles/views/musters.scss +++ b/assets/styles/views/musters.scss @@ -42,7 +42,7 @@ .card-officer{ text-align: left; color: $color-grey-light; - margin-bottom: 20px; + margin-bottom: 40px; } .card-officer-title{ text-align:left; @@ -55,3 +55,6 @@ .card .card-officer:last-child{ padding-botttom: 40px; } +.table{ + width: 100%; +} From 5a4728f543f723ec7ecf554a9632508c5f4c6b2b Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 1 Sep 2016 00:19:47 +0530 Subject: [PATCH 227/314] Fix header dropdown' --- app/templates/partials/header.hbs | 6 +- assets/scripts/index.js | 1 + assets/scripts/lib/dropdown.js | 327 ++++++++++++++++++++++++++++++ 3 files changed, 330 insertions(+), 4 deletions(-) create mode 100644 assets/scripts/lib/dropdown.js diff --git a/app/templates/partials/header.hbs b/app/templates/partials/header.hbs index fa8502c8..8858d612 100644 --- a/app/templates/partials/header.hbs +++ b/app/templates/partials/header.hbs @@ -8,11 +8,9 @@ R
    diff --git a/assets/scripts/index.js b/assets/scripts/index.js index c6edb615..fda3994a 100644 --- a/assets/scripts/index.js +++ b/assets/scripts/index.js @@ -8,6 +8,7 @@ import Performance from './containers/performance.jsx'; import ActiveLink from './lib/active-link'; ActiveLink.init(); +require('./lib/dropdown'); if (window.location.pathname === '/musters') { diff --git a/assets/scripts/lib/dropdown.js b/assets/scripts/lib/dropdown.js new file mode 100644 index 00000000..c165b033 --- /dev/null +++ b/assets/scripts/lib/dropdown.js @@ -0,0 +1,327 @@ +'use strict'; +var jQuery = require('jquery'); + + +var _createClass = (function() { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ('value' in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + return function(Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; +})(); + +function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError('Cannot call a class as a function'); + } +} + +var Dropdown = (function($) { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME = 'dropdown'; + var VERSION = '4.0.0'; + var DATA_KEY = 'bs.dropdown'; + var EVENT_KEY = '.' + DATA_KEY; + var DATA_API_KEY = '.data-api'; + var JQUERY_NO_CONFLICT = $.fn[NAME]; + + var Event = { + HIDE: 'hide' + EVENT_KEY, + HIDDEN: 'hidden' + EVENT_KEY, + SHOW: 'show' + EVENT_KEY, + SHOWN: 'shown' + EVENT_KEY, + CLICK: 'click' + EVENT_KEY, + CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY, + KEYDOWN_DATA_API: 'keydown' + EVENT_KEY + DATA_API_KEY + }; + + var ClassName = { + BACKDROP: 'dropdown-backdrop', + DISABLED: 'disabled', + OPEN: 'open' + }; + + var Selector = { + BACKDROP: '.dropdown-backdrop', + DATA_TOGGLE: '[data-toggle="dropdown"]', + FORM_CHILD: '.dropdown form', + ROLE_MENU: '[role="menu"]', + ROLE_LISTBOX: '[role="listbox"]', + NAVBAR_NAV: '.navbar-nav', + VISIBLE_ITEMS: '[role="menu"] li:not(.disabled) a, ' + '[role="listbox"] li:not(.disabled) a' + }; + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Dropdown = (function() { + function Dropdown(element) { + _classCallCheck(this, Dropdown); + + this._element = element; + + this._addEventListeners(); + } + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + // getters + + _createClass(Dropdown, [{ + key: 'toggle', + + // public + + value: function toggle() { + if (this.disabled || $(this).hasClass(ClassName.DISABLED)) { + return false; + } + + var parent = Dropdown._getParentFromElement(this); + var isActive = $(parent).hasClass(ClassName.OPEN); + + Dropdown._clearMenus(); + + if (isActive) { + return false; + } + + if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) { + + // if mobile we use a backdrop because click events don't delegate + var dropdown = document.createElement('div'); + dropdown.className = ClassName.BACKDROP; + $(dropdown).insertBefore(this); + $(dropdown).on('click', Dropdown._clearMenus); + } + + var relatedTarget = { + relatedTarget: this + }; + var showEvent = $.Event(Event.SHOW, relatedTarget); + + $(parent).trigger(showEvent); + + if (showEvent.isDefaultPrevented()) { + return false; + } + + this.focus(); + this.setAttribute('aria-expanded', 'true'); + + $(parent).toggleClass(ClassName.OPEN); + $(parent).trigger($.Event(Event.SHOWN, relatedTarget)); + + return false; + } + }, { + key: 'dispose', + value: function dispose() { + $.removeData(this._element, DATA_KEY); + $(this._element).off(EVENT_KEY); + this._element = null; + } + + // private + + }, { + key: '_addEventListeners', + value: function _addEventListeners() { + $(this._element).on(Event.CLICK, this.toggle); + } + + // static + + }], [{ + key: '_jQueryInterface', + value: function _jQueryInterface(config) { + return this.each(function() { + var data = $(this).data(DATA_KEY); + + if (!data) { + $(this).data(DATA_KEY, data = new Dropdown(this)); + } + + if (typeof config === 'string') { + data[config].call(this); + } + }); + } + }, { + key: '_clearMenus', + value: function _clearMenus(event) { + if (event && event.which === 3) { + return; + } + + var backdrop = $(Selector.BACKDROP)[0]; + if (backdrop) { + backdrop.parentNode.removeChild(backdrop); + } + + var toggles = $.makeArray($(Selector.DATA_TOGGLE)); + + for (var i = 0; i < toggles.length; i++) { + var _parent = Dropdown._getParentFromElement(toggles[i]); + var relatedTarget = { + relatedTarget: toggles[i] + }; + + if (!$(_parent).hasClass(ClassName.OPEN)) { + continue; + } + + if (event && event.type === 'click' && /input|textarea/i.test(event.target.tagName) && $.contains(_parent, event.target)) { + continue; + } + + var hideEvent = $.Event(Event.HIDE, relatedTarget); + $(_parent).trigger(hideEvent); + if (hideEvent.isDefaultPrevented()) { + continue; + } + + toggles[i].setAttribute('aria-expanded', 'false'); + + $(_parent).removeClass(ClassName.OPEN).trigger($.Event(Event.HIDDEN, relatedTarget)); + } + } + }, { + key: '_getParentFromElement', + value: function _getParentFromElement(element) { + var parent; + + function getSelectorFromElement(element) { + var selector = element.getAttribute('data-target'); + if (!selector) { + selector = element.getAttribute('href') || ''; + selector = /^#[a-z]/i.test(selector) ? selector : null; + } + return selector; + } + + var selector = getSelectorFromElement(element); + + if (selector) { + parent = $(selector)[0]; + } + + return parent || element.parentNode; + } + }, { + key: '_dataApiKeydownHandler', + value: function _dataApiKeydownHandler(event) { + if (!/(38|40|27|32)/.test(event.which) || /input|textarea/i.test(event.target.tagName)) { + return; + } + + event.preventDefault(); + event.stopPropagation(); + + if (this.disabled || $(this).hasClass(ClassName.DISABLED)) { + return; + } + + var parent = Dropdown._getParentFromElement(this); + var isActive = $(parent).hasClass(ClassName.OPEN); + + if (!isActive && event.which !== 27 || isActive && event.which === 27) { + + if (event.which === 27) { + var toggle = $(parent).find(Selector.DATA_TOGGLE)[0]; + $(toggle).trigger('focus'); + } + + $(this).trigger('click'); + return; + } + + var items = $.makeArray($(Selector.VISIBLE_ITEMS)); + + items = items.filter(function(item) { + return item.offsetWidth || item.offsetHeight; + }); + + if (!items.length) { + return; + } + + var index = items.indexOf(event.target); + + if (event.which === 38 && index > 0) { + // up + index--; + } + + if (event.which === 40 && index < items.length - 1) { + // down + index++; + } + + if (!~index) { + index = 0; + } + + items[index].focus(); + } + }, { + key: 'VERSION', + get: function get() { + return VERSION; + } + }]); + + return Dropdown; + })(); + + $(document).on( + Event.KEYDOWN_DATA_API, + Selector.DATA_TOGGLE, + Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, + Selector.ROLE_MENU, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, + Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API, + Dropdown._clearMenus).on(Event.CLICK_DATA_API, + Selector.DATA_TOGGLE, Dropdown.prototype.toggle).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, + function(e) { + e.stopPropagation(); + }); + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Dropdown._jQueryInterface; + $.fn[NAME].Constructor = Dropdown; + $.fn[NAME].noConflict = function() { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return Dropdown._jQueryInterface; + }; + + return Dropdown; +})(jQuery); + +module.exports = Dropdown; From f9a79479ab321998411794235ffc2be47a87ddf1 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Wed, 31 Aug 2016 14:51:41 -0400 Subject: [PATCH 228/314] include days_to_payment in district musters response --- app/helpers/musters_parser.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/helpers/musters_parser.js b/app/helpers/musters_parser.js index e276ba65..632ce2aa 100644 --- a/app/helpers/musters_parser.js +++ b/app/helpers/musters_parser.js @@ -116,6 +116,7 @@ exports.district = function(rows) { 'block_name': v[0].block_name, 'current_total': v[0].current_total, 'delayed_total': v[0].delayed_total, + 'days_to_payment': v[0].days_to_payment, 't2_total': v[0].t2_total, 't2_avg': v[0].t2_avg, 't5_total': v[0].t5_total, From 47b8a6f6599e537e88dbf868e4c1fcd34d5aeae5 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 1 Sep 2016 00:33:03 +0530 Subject: [PATCH 229/314] Fix profile translations --- app/locales/en_US/v1.js | 24 +++++++++++++++++++++++- app/locales/hi/v1.js | 24 +++++++++++++++++++++++- app/templates/partials/settings-nav.hbs | 4 ++-- app/templates/users/settings-account.hbs | 16 ++++++++-------- app/templates/users/settings-profile.hbs | 16 ++++++++-------- 5 files changed, 64 insertions(+), 20 deletions(-) diff --git a/app/locales/en_US/v1.js b/app/locales/en_US/v1.js index ac2a16cc..b50fa49a 100644 --- a/app/locales/en_US/v1.js +++ b/app/locales/en_US/v1.js @@ -22,7 +22,29 @@ module.exports = { work_code: 'WORK CODE', closure_date: 'CLOSURE DATE', days_pending: 'DAYS PENDING' - } + }, + profile: { + firstname: 'First Name', + lastname: 'Last Name', + profile: 'Profile', + account: 'Account', + work_email: 'Work Email', + mobile: 'Mobile', + personal_email: 'Personal Email', + lang : 'Language', + settings: 'Settings', + logout: 'Logout', + profile_settings: 'Profile Settings', + email_settings: 'Email Settings', + primary_email_msg: 'Your primary email address will be used for account-related notifications as well as any web-based operations.', + save: 'Update', + your_primary_email: 'Your primary email', + change_pass: 'Change password', + old_pass: 'Old password', + new_pass: 'New password', + pass_confirm:'Verify new password', + forgot_pass: 'I forgot my password' + }, }, app: { overview: { diff --git a/app/locales/hi/v1.js b/app/locales/hi/v1.js index 3a6824a6..b4cb798d 100644 --- a/app/locales/hi/v1.js +++ b/app/locales/hi/v1.js @@ -21,7 +21,29 @@ module.exports = { work_code: 'कार्य कोड', closure_date: 'मस्टर रोल बंद होने की तिथि', days_pending: 'DAYS PENDING' - } + }, + profile: { + firstname: 'मूल नाम', + lastname: 'उपनाम', + profile: 'प्रोफ़ाइल', + account: 'अकाउंट', + work_email: 'औपचारिक e-mail', + mobile: 'मोबाइल नंबर', + personal_email: 'निजी e-mail', + lang : 'भाषा', + settings: 'सेट्टिंग्स', + logout: 'लौग आउट', + profile_settings: 'आपकी प्रोफ़ाइल सेट्टिंग्स', + email_settings: 'E-Mail सेट्टिंग्स', + primary_email_msg: 'आपके अकाउंट से संबंधित संदेशों और इंटरनेट-संबंधित प्रक्रियाओं के लिए आपके मुख्य e-mail ID का उपयोग किया जाएगा.', + save: 'अद्यतन (update)', + your_primary_email: 'आपका मुख्य e-mail ID', + change_pass: 'पासवर्ड बदलें', + old_pass: 'पुराना पासवर्ड ', + new_pass: 'नया पासवर्ड ', + pass_confirm:'नये पासवर्ड को सत्यापित करें', + forgot_pass: 'मैं अपना पासवर्ड भूल गयी/गया' + }, }, app: { overview: { diff --git a/app/templates/partials/settings-nav.hbs b/app/templates/partials/settings-nav.hbs index ca50832b..fddf8185 100644 --- a/app/templates/partials/settings-nav.hbs +++ b/app/templates/partials/settings-nav.hbs @@ -1,4 +1,4 @@ diff --git a/app/templates/users/settings-account.hbs b/app/templates/users/settings-account.hbs index 808926e2..71594b55 100644 --- a/app/templates/users/settings-account.hbs +++ b/app/templates/users/settings-account.hbs @@ -7,20 +7,20 @@
    {{> flash}}
    Email Settings
    -

    {{t "/profile/primary_email_msg" credentials}}

    +

    {{t "/web/profile/primary_email_msg" credentials null}}

    - {{t "/profile/your_primary_email" credentials}} : {{credentials.email}} + {{t "/web/profile/your_primary_email" credentials null}} : {{credentials.email}}

    -
    {{t "/profile/change_pass" credentials}}
    +
    {{t "/web/profile/change_pass" credentials null}}
    - + - + - + {{> form_security}} - - {{t "/profile/forgot_pass" credentials}} + + {{t "/web/profile/forgot_pass" credentials null}}
    diff --git a/app/templates/users/settings-profile.hbs b/app/templates/users/settings-profile.hbs index be2f85cb..7bf3f5d2 100644 --- a/app/templates/users/settings-profile.hbs +++ b/app/templates/users/settings-profile.hbs @@ -5,18 +5,18 @@
    -
    {{t "/profile/profile_settings" credentials}}
    {{> flash}} -

    {{t "/profile/firstname" credentials}} : {{user.firstname}}

    -

    {{t "/profile/lastname" credentials}} : {{user.lastname}}

    +
    {{t "/web/profile/profile_settings" credentials null}}
    {{> flash}} +

    {{t "/web/profile/firstname" credentials null}} : {{user.firstname}}

    +

    {{t "/web/profile/lastname" credentials null}} : {{user.lastname}}

    - + - + - + - + {{> form_security}} - +
    From b0e163c70f4283941c54c2b53fd2181f476673ab Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 1 Sep 2016 00:40:38 +0530 Subject: [PATCH 230/314] Fix yar plugin and session in profile change --- app/controllers/users/settings-profile.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/users/settings-profile.js b/app/controllers/users/settings-profile.js index c37f5211..e7cc8a29 100644 --- a/app/controllers/users/settings-profile.js +++ b/app/controllers/users/settings-profile.js @@ -42,15 +42,15 @@ exports.postEditProfile = { }).then(function(user) { if (user) { // if the record exists in the db user.update(request.payload).then(function() { - request.auth.session.clear(); - request.auth.session.set(user); + request.cookieAuth.clear(); + request.cookieAuth.set(user); request.session.flash('success', 'Profile successfully saved'); return reply.redirect('/me/settings/profile'); }); } else { - request.session.flash('error', 'An internal server error occurred'); + request.yar.flash('error', 'An internal server error occurred'); return reply.redirect('/me/settings/profile'); } }); From be5e95382977cea32818e33c4ac81ab772d430b9 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 1 Sep 2016 00:48:26 +0530 Subject: [PATCH 231/314] Add navbar translation' --- app/controllers/users/settings-profile.js | 4 ++-- app/locales/en_US/v1.js | 5 +++++ app/locales/hi/v1.js | 5 +++++ app/templates/partials/header.hbs | 6 +++--- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/controllers/users/settings-profile.js b/app/controllers/users/settings-profile.js index e7cc8a29..ea65af1e 100644 --- a/app/controllers/users/settings-profile.js +++ b/app/controllers/users/settings-profile.js @@ -24,7 +24,7 @@ exports.postEditProfile = { }, failAction: function(request, reply, source, error) { // Boom bad request - request.session.flash('error', 'Bad request'); + request.yar.flash('error', 'Bad request'); return reply.redirect('/me/settings/profile'); } }, @@ -44,7 +44,7 @@ exports.postEditProfile = { user.update(request.payload).then(function() { request.cookieAuth.clear(); request.cookieAuth.set(user); - request.session.flash('success', 'Profile successfully saved'); + request.yar.flash('success', 'Profile successfully saved'); return reply.redirect('/me/settings/profile'); }); diff --git a/app/locales/en_US/v1.js b/app/locales/en_US/v1.js index b50fa49a..525d7ce4 100644 --- a/app/locales/en_US/v1.js +++ b/app/locales/en_US/v1.js @@ -3,6 +3,11 @@ module.exports = { $meta: 'English translation file', web: { + navigation: { + overview: 'OVERVIEW', + musters: 'MUSTERS', + performance: 'PERFORMANCE' + }, overview: { current: 'CURRENT', delayed: 'DELAYED', diff --git a/app/locales/hi/v1.js b/app/locales/hi/v1.js index b4cb798d..ab588f3b 100644 --- a/app/locales/hi/v1.js +++ b/app/locales/hi/v1.js @@ -3,6 +3,11 @@ module.exports = { $meta: 'Hindi translation file', web: { + navigation: { + overview: 'अवलोकन', + musters: 'MUSTERS', + performance: 'प्रदर्शन' + }, overview: { current: 'वर्तमान मस्टर्स', delayed: 'विलंबित मस्टर्स', diff --git a/app/templates/partials/header.hbs b/app/templates/partials/header.hbs index 8858d612..6a973ea6 100644 --- a/app/templates/partials/header.hbs +++ b/app/templates/partials/header.hbs @@ -15,9 +15,9 @@ {{else}}
    From d0fba3903cabd79655a02c4aff432def7e5be936 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Thu, 1 Sep 2016 10:40:33 -0400 Subject: [PATCH 232/314] Add translations; add colorblind scheme --- app/helpers/paydroid_parser.js | 24 ++++-------- app/locales/en_US/v2.js | 20 ++++++++-- app/locales/hi/v2.js | 70 ++++++++++++++++++++-------------- 3 files changed, 64 insertions(+), 50 deletions(-) diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index b09590d0..f1c4b2f7 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -592,15 +592,6 @@ exports.v2 = function(rows, role) { }, 'colors': { 'default': [ - // '#ffd300', - // '#18ff00', - // '#f57070', - // '#f8b128', - // '#f7f7f7', - // '#F22613', - // '#FDE3A7', - // '#f57070' - '#F15854', '#B2912F', '#F17CB0', @@ -610,14 +601,13 @@ exports.v2 = function(rows, role) { '#B276B2' ], 'colorblind': [ - '#ffd300', - '#18ff00', - '#f57070', - '#f8b128', - '#f7f7f7', - '#F22613', - '#FDE3A7', - '#f57070' + '#E69F00', + '#56B4E9', + '#009E73', + '#000000', + '#F0E442', + '#D55E00', + '#CC79A7' ] }, 'version': versionResponse[0].version diff --git a/app/locales/en_US/v2.js b/app/locales/en_US/v2.js index aa644f59..40ca0e07 100644 --- a/app/locales/en_US/v2.js +++ b/app/locales/en_US/v2.js @@ -15,6 +15,7 @@ module.exports = { view_cards: 'VIEW CARDS' }, cards: { + cards: 'Cards', musters_closing_today: 'Musters closing today', delayed_musters_1: 'Delayed musters', muster_details: 'Muster details', @@ -42,6 +43,7 @@ module.exports = { total: 'Total time for payment (overall)', all: 'Total time for payment (step-wise)' }, + statutory_limit: 'Statutory Limit', dates: { all_dates: 'All dates', past_3_months: 'Past 3 months' @@ -105,7 +107,8 @@ module.exports = { 'logout': 'Log out', 'cancel': 'Cancel' }, - general: 'Unable to log out of PayDash. Please contact the PayDash team if this issue persists.' + general: 'Unable to log out of PayDash. Please contact the PayDash team if this issue persists.', + logging_out: 'Logging out...' }, profile_success: 'Profile successfully updated.', profile_error: 'Unable to update profile. Please contact the PayDash team if this issue persists.', @@ -115,7 +118,10 @@ module.exports = { password_tooshort: 'Your new password must be at least 6 characters long.', password_network_error: 'Unable to change password. Please try again when you have network connectivity.', password_empty: 'Password cannot be empty', - requesting_change: 'Requesting password change...' + requesting_change: 'Requesting password change...', + update_available: 'New Update Available', + update: 'Update', + grant_permission:'Please grant permission to proceed' }, contact: { contact: 'Contact', @@ -138,6 +144,7 @@ module.exports = { delayed_musters: 'Delayed musters' }, cards: { + cards: 'Cards', days_to_payment: 'Avg. days to payment in last 3 months', musters_closing_today: 'Musters closing today', delayed_musters: 'Delayed musters', @@ -167,6 +174,7 @@ module.exports = { total: 'Total time for payment (overall)', all: 'Total time for payment (step-wise)' }, + statutory_limit: 'Statutory Limit', dates: { all_dates: 'All dates', past_3_months: 'Past 3 months' @@ -231,7 +239,8 @@ module.exports = { 'logout': 'Log out', 'cancel': 'Cancel' }, - general: 'Unable to log out of PayDash. Please contact the PayDash team if this issue persists.' + general: 'Unable to log out of PayDash. Please contact the PayDash team if this issue persists.', + logging_out: 'Logging out...' }, profile_success: 'Profile successfully updated.', profile_error: 'Unable to update profile. Please contact the PayDash team if this issue persists.', @@ -241,7 +250,10 @@ module.exports = { password_tooshort: 'Your new password must be at least 6 characters long.', password_network_error: 'Unable to change password. Please try again when you have network connectivity.', password_empty: 'Password cannot be empty', - requesting_change: 'Requesting password change...' + requesting_change: 'Requesting password change...', + update_available: 'New Update Available', + update: 'Update', + grant_permission:'Please grant permission to proceed' }, contact: { contact: 'Contact', diff --git a/app/locales/hi/v2.js b/app/locales/hi/v2.js index 944f5f2e..5c0ea92f 100644 --- a/app/locales/hi/v2.js +++ b/app/locales/hi/v2.js @@ -15,6 +15,7 @@ module.exports = { view_cards: 'कार्ड्स देखें' }, cards: { + cards: 'कार्ड्स', musters_closing_today: 'आज बंद हो रहे मस्टर्स', delayed_musters_1: 'विलंबित मस्टर्स', muster_details: 'मस्टर्स की विस्तार से जानकारी', @@ -42,6 +43,7 @@ module.exports = { total:'भुगतान प्रक्रिया पूरी करने में लगे दिन (बिना विभाजन के)', all:'भुगतान प्रक्रिया पूरी करने में लगे दिन (पड़ावों में विभाजित)', }, + statutory_limit: 'क़ानून द्वारा निर्धारित समया सीमा', dates: { all_dates: 'सभी तारीखें', past_3_months: 'पिछले 3 महीने' @@ -63,15 +65,15 @@ module.exports = { }, profile: { profile: 'प्रोफ़ाइल', - edit: 'EDIT', - save:'SAVE', - updating:'UPDATING...', + edit: 'प्रोफ़ाइल बदलें', + save:'प्रोफ़ाइल सेव करें', + updating:'अपडेट होने की प्रक्रिया जारी है...', firstname: 'मूल नाम', lastname: 'उपनाम', mobile: 'मोबाइल नंबर', personal_email: 'निजी e-mail', work_email: 'औपचारिक e-mail', - colorblind: 'Use Colorblind-Safe Theme', + colorblind: 'वर्णांधता (color blindness) के लिए अनुकूल रंग प्रणाली का उपयोग करें', lang: 'भाषा', eng: 'English', hindi: 'Hindi', @@ -85,12 +87,12 @@ module.exports = { forgot_pass: 'मैं अपना पासवर्ड भूल गयी/गया', change_pass_button: 'पासवर्ड बदलें' }, - search: 'Search for TA/GRS...', + search: 'उप यंत्री/ GRS का नाम खोजें', sort: { current_total: 'आज बंद हो रहे मस्टर्स', delayed_total: 'विलंबित मस्टर्स', - name: 'Name', - designation: 'Designation' + name: 'नाम', + designation: 'पद' }, messages: { login: { @@ -105,20 +107,24 @@ module.exports = { 'logout': 'Log out', 'cancel': 'Cancel' }, - general: 'हमे खेद है कि आप log out करने में विफल रहे| यदि यह समस्या कायम रहती है तो PayDash दल से संपर्क करें|' + general: 'हमे खेद है कि आप log out करने में विफल रहे| यदि यह समस्या कायम रहती है तो PayDash दल से संपर्क करें|', + logging_out: 'आप लोग आउट हो रहे हैं...' }, - profile_success: 'Profile successfully updated.', - profile_error: 'Unable to update profile. Please contact the PayDash team if this problem persists.', + profile_success: 'आपकी प्रोफ़ाइल सफलतापूर्वक अपडेट हो चुकी है', + profile_error: 'प्रोफ़ाइल अपडेट करने की प्रक्रिया असफल रही| यदि यह समस्या कायम रहती है तो PayDash दल से संपर्क करें|', password_success: 'पासवर्ड सफलतापूर्वक बदला जा चुका है| कृपया नये पासवर्ड का उपयोग कर लॉग इन करें|', password_wrong_old: 'पुराना पासवर्ड ग़लत है| सहयता के लिए PayDash दल से संपर्क करें|', password_new_nomatch: 'नया पासवर्ड मेल नही ख़ाता|', password_tooshort: 'आपके नये पासवर्ड की लंबाई कम से कम 6 अक्षर होनी चाहिए|', - password_network_error: 'Unable to change password. Please try again when you have network connectivity.', - password_empty: 'Password cannot be empty', - requesting_change: 'Requesting password change...' + password_network_error: 'पासवर्ड बदलने की प्रक्रिया असफल रही| कृपया नेटवर्क सशक्त होने पर दोबारा कोशिश करें|', + password_empty: 'पासवर्ड रिक्त नही रह सकता', + requesting_change: 'पासवर्ड बदलने की प्रक्रिया जारी है', + update_available: 'नया अपडेट उपलब्ध है', + update: 'अपडेट', + grant_permission: 'कृपया प्रक्रिया आगे बढ़ाने के लिए अनुमति दें' }, contact: { - contact: 'Contact', + contact: 'संपर्क करें', gmail: 'Gmail', phone: 'Phone' }, @@ -138,6 +144,7 @@ module.exports = { delayed_musters: 'विलंबित मस्टर्स' }, cards: { + cards: 'कार्ड्स', days_to_payment: 'पिछले 3 महीनों में किए गये हर भुगतान में लगे औसत दिन', musters_closing_today: 'आज बंद हो रहे मस्टर्स', delayed_musters: 'विलंबित मस्टर्स', @@ -167,6 +174,7 @@ module.exports = { total:'भुगतान प्रक्रिया पूरी करने में लगे दिन (बिना विभाजन के)', all:'भुगतान प्रक्रिया पूरी करने में लगे दिन (पड़ावों में विभाजित)', }, + statutory_limit: 'क़ानून द्वारा निर्धारित समया सीमा', dates: { all_dates: 'सभी तारीखें', past_3_months: 'पिछले 3 महीने' @@ -188,15 +196,15 @@ module.exports = { }, profile: { profile: 'प्रोफ़ाइल', - edit: 'EDIT', - save:'SAVE', - updating:'UPDATING...', + edit: 'प्रोफ़ाइल बदलें', + save:'प्रोफ़ाइल सेव करें', + updating:'अपडेट होने की प्रक्रिया जारी है...', firstname: 'मूल नाम', lastname: 'उपनाम', mobile: 'मोबाइल नंबर', personal_email: 'निजी e-mail', work_email: 'औपचारिक e-mail', - colorblind: 'Use Colorblind-Safe Theme', + colorblind: 'वर्णांधता (color blindness) के लिए अनुकूल रंग प्रणाली का उपयोग करें', lang: 'भाषा', eng: 'English', hindi: 'Hindi', @@ -210,13 +218,13 @@ module.exports = { forgot_pass: 'मैं अपना पासवर्ड भूल गयी/गया', change_pass_button: 'पासवर्ड बदलें' }, - search: 'Search for Block or Officer Name...', + search: 'जनपद/प्रखंड या अफ़सर का नाम खोजें', sort: { current_total: 'आज बंद हो रहे मस्टर्स', - delayed_total: 'Delayed total', + delayed_total: 'विलंबित मस्टर्स', days_to_payment: 'पिछले 3 महीनों में किए गये हर भुगतान में लगे औसत दिन', - block_name: 'Block name', - ceo_name: 'Block CEO name' + block_name: 'जनपद/प्रखंड का नाम', + ceo_name: 'जनपद/प्रखंड CEO का नाम' }, messages: { login: { @@ -231,20 +239,24 @@ module.exports = { 'logout': 'Log out', 'cancel': 'Cancel' }, - general: 'हमे खेद है कि आप log out करने में विफल रहे| यदि यह समस्या कायम रहती है तो PayDash दल से संपर्क करें|' + general: 'हमे खेद है कि आप log out करने में विफल रहे| यदि यह समस्या कायम रहती है तो PayDash दल से संपर्क करें|', + logging_out: 'आप लोग आउट हो रहे हैं...' }, - profile_success: 'Profile successfully updated.', - profile_error: 'Unable to update profile. Please contact the PayDash team if this problem persists.', + profile_success: 'आपकी प्रोफ़ाइल सफलतापूर्वक अपडेट हो चुकी है', + profile_error: 'प्रोफ़ाइल अपडेट करने की प्रक्रिया असफल रही| यदि यह समस्या कायम रहती है तो PayDash दल से संपर्क करें|', password_success: 'पासवर्ड सफलतापूर्वक बदला जा चुका है| कृपया नये पासवर्ड का उपयोग कर लॉग इन करें|', password_wrong_old: 'पुराना पासवर्ड ग़लत है| सहयता के लिए PayDash दल से संपर्क करें|', password_new_nomatch: 'नया पासवर्ड मेल नही ख़ाता|', password_tooshort: 'आपके नये पासवर्ड की लंबाई कम से कम 6 अक्षर होनी चाहिए|', - password_network_error: 'Unable to change password. Please try again when you have network connectivity.', - password_empty: 'Password cannot be empty', - requesting_change: 'Requesting password change...' + password_network_error: 'पासवर्ड बदलने की प्रक्रिया असफल रही| कृपया नेटवर्क सशक्त होने पर दोबारा कोशिश करें|', + password_empty: 'पासवर्ड रिक्त नही रह सकता', + requesting_change: 'पासवर्ड बदलने की प्रक्रिया जारी है', + update_available: 'नया अपडेट उपलब्ध है', + update: 'अपडेट', + grant_permission: 'कृपया प्रक्रिया आगे बढ़ाने के लिए अनुमति दें' }, contact: { - contact: 'Contact', + contact: 'संपर्क करें', gmail: 'Gmail', phone: 'Phone' }, From 4bb4c05a19dcc2bc3b834ef792d22b44a47e1430 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Fri, 2 Sep 2016 10:09:27 -0400 Subject: [PATCH 233/314] Update translations --- app/locales/en_US/v2.js | 4 ++-- app/locales/hi/v2.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/locales/en_US/v2.js b/app/locales/en_US/v2.js index 40ca0e07..34ee4241 100644 --- a/app/locales/en_US/v2.js +++ b/app/locales/en_US/v2.js @@ -137,8 +137,8 @@ module.exports = { district: { paydash: 'PayDash', overview: { - view_your_blocks: 'View your blocks\' performance', - show_blocks: 'SHOW BLOCKS', + view_your_blocks: 'View your {blocks_total} blocks', + show_blocks: 'GO TO BLOCKS', days_to_payment: 'Avg. days to payment in last 3 months', musters_closing_today: 'Musters closing today', delayed_musters: 'Delayed musters' diff --git a/app/locales/hi/v2.js b/app/locales/hi/v2.js index 5c0ea92f..668eabb0 100644 --- a/app/locales/hi/v2.js +++ b/app/locales/hi/v2.js @@ -137,8 +137,8 @@ module.exports = { district: { paydash: 'पे-डॅश', overview: { - view_your_blocks: 'अपने जनपदों/प्रखंडों का प्रदर्शन देखें', - show_blocks: 'SHOW BLOCKS', + view_your_blocks: 'अपने ज़िले के {blocks_total} जनपदों का प्रदर्शन देखें', + show_blocks: 'जनपद देखें', days_to_payment: 'पिछले 3 महीनों में किए गये हर भुगतान में लगे औसत दिन', musters_closing_today: 'आज बंद हो रहे मस्टर्स', delayed_musters: 'विलंबित मस्टर्स' From c91a1bad20c0c7101b96857b99dfef7f54f49388 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Fri, 2 Sep 2016 11:03:11 -0400 Subject: [PATCH 234/314] Add 8th color --- app/helpers/paydroid_parser.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index f1c4b2f7..9719a5a9 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -598,7 +598,8 @@ exports.v2 = function(rows, role) { '#60BD68', '#FAA43A', '#5DA5DA', - '#B276B2' + '#B276B2', + '#F15854', ], 'colorblind': [ '#E69F00', @@ -607,7 +608,8 @@ exports.v2 = function(rows, role) { '#000000', '#F0E442', '#D55E00', - '#CC79A7' + '#CC79A7', + '#E69F00', ] }, 'version': versionResponse[0].version From ae4e273cdc550e6a9b9768115e2819d5f7cf481a Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Fri, 2 Sep 2016 11:03:30 -0400 Subject: [PATCH 235/314] Add 8th color --- app/helpers/paydroid_parser.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index 9719a5a9..2a0397d2 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -599,7 +599,7 @@ exports.v2 = function(rows, role) { '#FAA43A', '#5DA5DA', '#B276B2', - '#F15854', + '#F15854' ], 'colorblind': [ '#E69F00', @@ -609,7 +609,7 @@ exports.v2 = function(rows, role) { '#F0E442', '#D55E00', '#CC79A7', - '#E69F00', + '#E69F00' ] }, 'version': versionResponse[0].version From 8ea342dcd9c76b168d65bd8cf07c9eb1eb906ab1 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Fri, 2 Sep 2016 11:30:44 -0400 Subject: [PATCH 236/314] Don't capitalize employee names in API, move it to the app --- app/helpers/paydroid_parser.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index 2a0397d2..bbc9159b 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -234,7 +234,7 @@ exports.v2 = function(rows, role) { }) .rollup(function(v) { return { - 'name': v[0].name.toUpperCase(), + 'name': v[0].name, 'staff_id': v[0].staff_id, 'designation': Utils.getDesignation(v[0].task_assign, state_code), 'mobile': v[0].mobile_no, @@ -609,7 +609,7 @@ exports.v2 = function(rows, role) { '#F0E442', '#D55E00', '#CC79A7', - '#E69F00' + '#E69F00'e ] }, 'version': versionResponse[0].version From 470ba0714c90b70288f8eae54f3e4563660d0c47 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Fri, 2 Sep 2016 11:37:05 -0400 Subject: [PATCH 237/314] Typo --- app/helpers/paydroid_parser.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index bbc9159b..e5e5c986 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -609,7 +609,7 @@ exports.v2 = function(rows, role) { '#F0E442', '#D55E00', '#CC79A7', - '#E69F00'e + '#E69F00' ] }, 'version': versionResponse[0].version From dbea6a4cdd24d3074c7d66c33b5be604e7d2b915 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Fri, 2 Sep 2016 12:03:33 -0400 Subject: [PATCH 238/314] Update 8th color --- app/helpers/paydroid_parser.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index e5e5c986..4e75231d 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -599,7 +599,7 @@ exports.v2 = function(rows, role) { '#FAA43A', '#5DA5DA', '#B276B2', - '#F15854' + '#97D19C' ], 'colorblind': [ '#E69F00', @@ -609,7 +609,7 @@ exports.v2 = function(rows, role) { '#F0E442', '#D55E00', '#CC79A7', - '#E69F00' + '#0072b2' ] }, 'version': versionResponse[0].version From 67a1787e4e202db4734e36ffd78d2f03a96c4339 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Mon, 5 Sep 2016 00:26:51 +0530 Subject: [PATCH 239/314] Wrap up charts --- app/controllers/performance/performance.js | 5 +- app/locales/en_US/v1.js | 59 ++++++++++++-- app/locales/hi/v1.js | 61 ++++++++++++-- .../scripts/components/musters/block-card.jsx | 11 ++- .../performance/comparison-chart.jsx | 80 ++++++++++++++----- .../components/performance/overview-chart.jsx | 18 ++--- assets/scripts/containers/performance.jsx | 13 ++- assets/styles/views/performance.scss | 3 +- 8 files changed, 200 insertions(+), 50 deletions(-) diff --git a/app/controllers/performance/performance.js b/app/controllers/performance/performance.js index aca1d75b..37b7d3a4 100644 --- a/app/controllers/performance/performance.js +++ b/app/controllers/performance/performance.js @@ -32,12 +32,11 @@ exports.getData = { data.config = { role: role, headers: ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn'], - labels: Translate('/payment_steps_labels', request.auth.credentials), - y_axis_label: Translate('/y_axis_labels', request.auth.credentials), - compare_chart_labels: Translate('/compare_chart_labels', request.auth.credentials), comparison_lines: role === 'block' ? ['district', 'state'] : ['state'] }; + data.translation = Translate('/web/performance', request.auth.credentials, null); + reply(data); }); } diff --git a/app/locales/en_US/v1.js b/app/locales/en_US/v1.js index 525d7ce4..a74f1b78 100644 --- a/app/locales/en_US/v1.js +++ b/app/locales/en_US/v1.js @@ -22,12 +22,61 @@ module.exports = { current_musters: 'CURRENT MUSTERS', delayed_musters: 'Delayed MUSTERS', msr_no: 'MUSTER NO.', - panchayat_name :'PANCHAYAT NAME', - work_name : 'WORK NAME', + panchayat_name: 'PANCHAYAT NAME', + work_name: 'WORK NAME', work_code: 'WORK CODE', closure_date: 'CLOSURE DATE', days_pending: 'DAYS PENDING' }, + performance: { + overview: { + title: { + $filter: 'role', + district: 'District Performance', + block: 'Your Block/Panchayat\'s Performance', + $default: 'Overview Performance' + }, + description: { + $filter: 'role', + district: 'Average number of days to complete each step of the payment process in your district.', + block: 'Average number of days to complete each step of the payment process in your block.', + $default: 'Average number of days to complete each step of the payment process in your region.' + }, + labels: [ + 'Muster roll closure to muster roll entry', + 'Muster roll entry to wage list generation', + 'Wage list generation to wage list sent', + 'Wage list sent to FTO generation', + 'FTO generation to first signature', + 'First signature to second signature', + 'Second signature to processed by bank' + ], + tooltip: 'The chart at right shows the average number of days to complete each step of the payment process for payments that reached beneficiaries’ bank accounts on the given date. Therefore, only completed payments are displayed.', + }, + comparison: { + title: { + $filter: 'role', + district: 'Benchmarking Your Performance', + block: 'Benchmarking Your Performance', + $default: 'Benchmarking Your Performance' + }, + description: { + $filter: 'role', + district: 'Compare your performance with averages for your state.', + block: 'Compare your performance with averages for your district and state.', + $default: 'Compare your performance with averages for other regions.' + }, + labels: { + 'state': 'state average', + 'district': 'district average', + 'block': 'block average', + 'panchayat': 'panchayat average', + }, + tooltip: 'The chart at right shows the average number of days to complete each step of the payment process for payments that reached beneficiaries’ bank accounts on the given date. Therefore, only completed payments are displayed.', + }, + y_axis_label: 'Days to complete process', + total_trans: 'Total transactions on' + }, profile: { firstname: 'First Name', lastname: 'Last Name', @@ -36,7 +85,7 @@ module.exports = { work_email: 'Work Email', mobile: 'Mobile', personal_email: 'Personal Email', - lang : 'Language', + lang: 'Language', settings: 'Settings', logout: 'Logout', profile_settings: 'Profile Settings', @@ -47,9 +96,9 @@ module.exports = { change_pass: 'Change password', old_pass: 'Old password', new_pass: 'New password', - pass_confirm:'Verify new password', + pass_confirm: 'Verify new password', forgot_pass: 'I forgot my password' - }, + }, }, app: { overview: { diff --git a/app/locales/hi/v1.js b/app/locales/hi/v1.js index ab588f3b..47e460ab 100644 --- a/app/locales/hi/v1.js +++ b/app/locales/hi/v1.js @@ -5,7 +5,7 @@ module.exports = { web: { navigation: { overview: 'अवलोकन', - musters: 'MUSTERS', + musters: 'मस्टर्स', performance: 'प्रदर्शन' }, overview: { @@ -21,12 +21,61 @@ module.exports = { officers: 'OFFICERS', delayed_musters: 'विलंबित मस्टर्स', msr_no: 'MUSTER NO.', - panchayat_name :'PANCHAYAT NAME', - work_name : 'कार्य नाम', + panchayat_name: 'PANCHAYAT NAME', + work_name: 'कार्य नाम', work_code: 'कार्य कोड', closure_date: 'मस्टर रोल बंद होने की तिथि', days_pending: 'DAYS PENDING' }, + performance: { + overview: { + title: { + $filter: 'role', + district: 'आपके ज़िले का प्रदर्शन', + block: 'आपके प्रखंड/जनपद का प्रदर्शन', + $default: 'अवलोकन प्रदर्शन' + }, + description: { + $filter: 'role', + district: 'आपके ज़िले में मज़दूरी भुगतान के हर एक पड़ाव पर लगे औसत दिन', + block: 'आपके प्रखंड/जनपद में मज़दूरी भुगतान के हर एक पड़ाव पर लगे औसत दिन', + $default: 'आपके क्षेत्रों में मज़दूरी भुगतान के हर एक पड़ाव पर लगे औसत दिन' + }, + tooltip: 'यह ग्राफ़ MGNREGA मज़दूरी भुगतान में लगा औसत समय दिखाता है| वर्णित तिथियों पर हुए भुगतान में लगे समय को 7 पड़ावों में बाटा गया है| इसलिए, केवल पूरे हुए भुगतान का डाटा दिखाया जा रहा है|', + labels: [ + 'मस्टर रोल बंद से डाटा एंट्री का समय', + 'डाटा एंट्री से वेज लिस्ट बनाने का समय', + 'वेज लिस्ट बनाने से वेज लिस्ट भेजने का समय', + 'वेज लिस्ट भेजने से FTO बनाने का समय', + 'FTO बनाने से पहले हस्ताक्षर का समय', + 'पहले हस्ताक्षर से दूसरे हस्ताक्षर का समय', + 'दूसरे हस्ताक्षर से बैंक की कारवाई के समापन का समय' + ], + }, + comparison: { + title: { + $filter: 'role', + district: 'आपके प्रदर्शन की तुलना', + block: 'आपके प्रदर्शन की तुलना', + $default: 'आपके प्रदर्शन की तुलना' + }, + description: { + $filter: 'role', + district: 'अपने ज़िले के औसत प्रदर्शन की तुलना राज्य के औसत प्रदर्शन से करें', + block: 'अपने प्रखंड/जनपद के औसत प्रदर्शन की तुलना ज़िले और राज्य के औसत प्रदर्शन से करें ', + $default: 'अपने प्रखंड/जनपद के औसत प्रदर्शन की तुलना अन्य क्षेत्रों के औसत प्रदर्शन से करें' + }, + labels: { + 'state': 'राज्य औसत', + 'district': 'ज़िला औसत', + 'block': 'प्रखंड औसत', + 'panchayat': 'जनपद औसत', + }, + tooltip: 'यह ग्राफ़ MGNREGA मज़दूरी भुगतान में लगा औसत समय दिखाता है| वर्णित तिथियों पर हुए भुगतान में लगे समय को 7 पड़ावों में बाटा गया है| इसलिए, केवल पूरे हुए भुगतान का डाटा दिखाया जा रहा है|', + }, + y_axis_labels: 'प्रक्रिया पूरी करने में लगे दिन', + total_trans: 'तिथि : कुल भुगतानों की संख्या-' + }, profile: { firstname: 'मूल नाम', lastname: 'उपनाम', @@ -35,7 +84,7 @@ module.exports = { work_email: 'औपचारिक e-mail', mobile: 'मोबाइल नंबर', personal_email: 'निजी e-mail', - lang : 'भाषा', + lang: 'भाषा', settings: 'सेट्टिंग्स', logout: 'लौग आउट', profile_settings: 'आपकी प्रोफ़ाइल सेट्टिंग्स', @@ -46,9 +95,9 @@ module.exports = { change_pass: 'पासवर्ड बदलें', old_pass: 'पुराना पासवर्ड ', new_pass: 'नया पासवर्ड ', - pass_confirm:'नये पासवर्ड को सत्यापित करें', + pass_confirm: 'नये पासवर्ड को सत्यापित करें', forgot_pass: 'मैं अपना पासवर्ड भूल गयी/गया' - }, + }, }, app: { overview: { diff --git a/assets/scripts/components/musters/block-card.jsx b/assets/scripts/components/musters/block-card.jsx index 6037dd46..8758d539 100644 --- a/assets/scripts/components/musters/block-card.jsx +++ b/assets/scripts/components/musters/block-card.jsx @@ -16,6 +16,13 @@ const BlockCard = React.createClass({ }; }, render: function(){ + + if(this.props.data.delayed_musters.length>0){ + var delayed_table =
    ; + } + if(this.props.data.current_musters.length>0){ + var current_table =
    ; + } return (
    @@ -36,8 +43,8 @@ const BlockCard = React.createClass({
    -
    -
    + {delayed_table} + {current_table}
    diff --git a/assets/scripts/components/performance/comparison-chart.jsx b/assets/scripts/components/performance/comparison-chart.jsx index d3e7d246..b4a9d302 100644 --- a/assets/scripts/components/performance/comparison-chart.jsx +++ b/assets/scripts/components/performance/comparison-chart.jsx @@ -11,8 +11,10 @@ const ComparisonChart = React.createClass({ getInitialState: function(){ return { - active_step: 1 - }; + active_step: 1, + active_lines: [], + comparison_lines:[] + }; }, loadChart: function(){ @@ -25,15 +27,11 @@ const ComparisonChart = React.createClass({ return; } - var comparison_lines = _this.props.config.comparison_lines.slice(0); - comparison_lines.push(_this.props.activeRegion.region_type); - - comparison_lines.forEach(function(comparison_line, index) { + _this.state.active_lines.forEach(function(comparison_line, index) { var region = Region.find(_this.props.activeRegion, _this.props.performance, comparison_line); - labels.push(region[comparison_line + '_name'] + ' ' + _this.props.config.compare_chart_labels[comparison_line]); - + labels.push(region[comparison_line + '_name'] + ' ' + _this.props.translation.comparison.labels[comparison_line]); var line_data = Parser.lines({ data: region.data, @@ -114,37 +112,75 @@ const ComparisonChart = React.createClass({ }); this.loadChart(); }, + lineChange: function(event){ + + var active_compare_lines = []; + D3.selectAll('.regionSelector').each(function() { + if (this.checked === true) { + active_compare_lines.push(this.value); + } + }); + this.setState({ + active_lines : active_compare_lines + }); + this.loadChart(); + }, componentDidMount: function() { this.loadChart(); }, componentDidUpdate: function(){ this.loadChart(); }, + componentWillReceiveProps: function(nextProps){ + + if(!nextProps.activeRegion) { + return; + } + var comparison_lines = nextProps.config.comparison_lines.slice(0); + comparison_lines.push(nextProps.activeRegion.region_type); + this.setState({ + comparison_lines : comparison_lines, + active_lines : comparison_lines + }); + }, render: function(){ + var _this = this; return (
    -

    Benchmarking Your Performance

    +

    {this.props.translation && this.props.translation.comparison.title}

    - Compare your performance with averages for your district and state. - + {this.props.translation && this.props.translation.comparison.description} +

    -
    -
    -
    + { + this.state.comparison_lines.map(function(line, i) { + + var region = Region.find(_this.props.activeRegion, _this.props.performance, line); + var label = region[line + '_name'] + ' ' + _this.props.translation.comparison.labels[line]; + var selected = _this.state.active_lines.indexOf(line) !== -1; + return ( +
    + +
    + ); + }) + }
    -
    Total transactions on
    +
    {this.props.translation && this.props.translation.total_trans}
    {if (el){this.elem = el;}}}>
    diff --git a/assets/scripts/components/performance/overview-chart.jsx b/assets/scripts/components/performance/overview-chart.jsx index 8b6a9287..7f6bf7c2 100644 --- a/assets/scripts/components/performance/overview-chart.jsx +++ b/assets/scripts/components/performance/overview-chart.jsx @@ -54,9 +54,9 @@ const OverviewChart = React.createClass({ label: 'Statutory Limit' }], point_size : 3.5, - legend: _this.props.config.labels, + legend: _this.props.translation.overview.labels, legend_target: '.region_legend', - y_label: _this.props.config.y_axis_label, + y_label: _this.props.translation.y_axis_label, mouseover: function(d, i) { if (!d.values) { d.values = [d]; @@ -65,14 +65,14 @@ const OverviewChart = React.createClass({ for (i = 1; i <= parsed_data.length; i++) { var l_span = D3.select(legend_target + ' .mg-line' + i + '-legend-color'); l_span.text(' '); - l_span.text('— ' + _this.props.config.labels[i - 1]); + l_span.text('— ' + _this.props.translation.overview.labels[i - 1]); } } d.values.forEach(function(val, index) { var l_span = D3.select(legend_target + ' .mg-line' + val.line_id + '-legend-color'); l_span.text(' '); var no_days = d.values[index - 1] ? (val.value - d.values[index - 1].value).toFixed(0) : (val.value).toFixed(0); - l_span.text('— ' + _this.props.config.labels[val.line_id - 1] + ' : ' + no_days); + l_span.text('— ' + _this.props.translation.overview.labels[val.line_id - 1] + ' : ' + no_days); var format = D3.time.format('%b %Y'); D3.select('#region_performance_total_trans').text(format(val.date) + ': ' + val.total_trans); }); @@ -85,7 +85,7 @@ const OverviewChart = React.createClass({ d.values.forEach(function(val, index) { var l_span = D3.select(legend_target + ' .mg-line' + val.line_id + '-legend-color'); l_span.text(' '); - l_span.text('— ' + _this.props.config.labels[index]); + l_span.text('— ' + _this.props.translation.overview.labels[index]); }); } }); @@ -100,13 +100,13 @@ const OverviewChart = React.createClass({ return (
    -

    Your Block's Performance

    +

    {this.props.translation && this.props.translation.overview.title}

    - Average number of days to complete each step of the payment process in your block. - + {this.props.translation && this.props.translation.overview.description} +

    -
    Total transactions on
    +
    {this.props.translation && this.props.translation.total_trans}
    {if (el){this.elem = el;}}}>
    diff --git a/assets/scripts/containers/performance.jsx b/assets/scripts/containers/performance.jsx index 766057fe..80fe26e9 100644 --- a/assets/scripts/containers/performance.jsx +++ b/assets/scripts/containers/performance.jsx @@ -16,6 +16,7 @@ const Overview = React.createClass({ _this.setState({ config: json.config, performance: json.performance, + translation: json.translation, isFetching : false, }); }) @@ -45,9 +46,17 @@ const Overview = React.createClass({ return (
    - +
    - +
    ); } diff --git a/assets/styles/views/performance.scss b/assets/styles/views/performance.scss index aa47f1fa..89a52232 100644 --- a/assets/styles/views/performance.scss +++ b/assets/styles/views/performance.scss @@ -46,7 +46,8 @@ .button--pc, .button--pc:hover, .button--pc:focus { - font-size: 1rem; + font-size: 1.2rem; text-transform: none; width: 100%; + color: $color-grey-darkest } From 275a682411c96da4c5687d7f36edee284c04aba6 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Mon, 5 Sep 2016 15:59:15 +0530 Subject: [PATCH 240/314] Fix bug in district overview graph --- .../components/musters/district-card.jsx | 67 ++++++++++--------- .../components/performance/overview-chart.jsx | 11 +-- .../scripts/components/performance/subnav.jsx | 1 - assets/scripts/lib/region.js | 45 +++++++++++++ 4 files changed, 84 insertions(+), 40 deletions(-) diff --git a/assets/scripts/components/musters/district-card.jsx b/assets/scripts/components/musters/district-card.jsx index dcd5d1b4..88c1cae8 100644 --- a/assets/scripts/components/musters/district-card.jsx +++ b/assets/scripts/components/musters/district-card.jsx @@ -37,7 +37,7 @@ const DistrictCard = React.createClass({ { this.props.data.officers.map(function(officer, i) { return ( -
    +
    {officer.name}
    {officer.designation} @@ -51,36 +51,41 @@ const DistrictCard = React.createClass({

    MUISTER DETAILS

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    StepTotalAverage
    T+2{this.props.data.t2_total}{this.props.data.t2_avg}
    T+5{this.props.data.t5_total}{this.props.data.t5_avg}
    T+6{this.props.data.t6_total}{this.props.data.t6_avg}
    T+7{this.props.data.t7_total}{this.props.data.t7_avg}
    T+8{this.props.data.t8_total}{this.props.data.t8_avg}
    StepTotalAverage
    T+2{this.props.data.t2_total}{this.props.data.t2_avg}
    T+5{this.props.data.t5_total}{this.props.data.t5_avg}
    T+6{this.props.data.t6_total}{this.props.data.t6_avg}
    T+7{this.props.data.t7_total}{this.props.data.t7_avg}
    T+8{this.props.data.t8_total}{this.props.data.t8_avg}
    diff --git a/assets/scripts/components/performance/overview-chart.jsx b/assets/scripts/components/performance/overview-chart.jsx index 7f6bf7c2..44eeace0 100644 --- a/assets/scripts/components/performance/overview-chart.jsx +++ b/assets/scripts/components/performance/overview-chart.jsx @@ -5,20 +5,15 @@ import MG from '../../lib/mg'; const D3 = require('d3'); const Parser = require('../../lib/parser'); +const Region = require('../../lib/region'); const OverviewChart = React.createClass({ loadChart: function(){ - var data; var _this = this; - - if(_this.props.activeRegion && _this.props.activeRegion.region_type === 'block'){ - data = _this.props.performance[_this.props.activeRegion.region_type][_this.props.activeRegion.block_index].data; - } - else if(_this.props.activeRegion && _this.props.activeRegion.region_type === 'panchayat'){ - data = _this.props.performance[_this.props.activeRegion.region_type][_this.props.activeRegion.block_index].data[_this.props.activeRegion.panchayat_index].data; - }else { + var data = Region.overview_data(_this.props.config.role, _this.props.activeRegion, _this.props.performance); + if(!data){ return; } var legend_target = '.region_legend'; diff --git a/assets/scripts/components/performance/subnav.jsx b/assets/scripts/components/performance/subnav.jsx index 3fa7d844..65594c17 100644 --- a/assets/scripts/components/performance/subnav.jsx +++ b/assets/scripts/components/performance/subnav.jsx @@ -21,7 +21,6 @@ const Subnav = React.createClass({ setValue (value) { this.setState({ value }); this.props.onRegionChange(value); - // Load graph logic here }, render: function(){ var list = Regions.list(this.props.performance, this.props.role); diff --git a/assets/scripts/lib/region.js b/assets/scripts/lib/region.js index 301b1479..38ce59fa 100644 --- a/assets/scripts/lib/region.js +++ b/assets/scripts/lib/region.js @@ -25,6 +25,27 @@ exports.list = function(performance, role) { }); } + if (role === 'district') { + performance['block'].forEach(function(district, district_index) { + regions.push({ + value: district.district_code, + label: district.district_name, + region_type: 'district', + class: 'select_parent', + district_index: district_index + }); + district.data.forEach(function(block, block_index) { + regions.push({ + value: block.block_code, + label: block.block_name, + region_type: 'block', + class: 'select_child', + block_index: block_index, + district_index: district_index + }); + }); + }); + } return regions; }; @@ -38,3 +59,27 @@ exports.find = function(activeRegion, performance, comparison_line) { return region = performance[comparison_line]; } }; + +exports.overview_data = function(role, activeRegion, performance) { + var data; + + if (role === 'block') { + if (activeRegion && activeRegion.region_type === 'block') { + data = performance[activeRegion.region_type][activeRegion.block_index].data; + } else if (activeRegion && activeRegion.region_type === 'panchayat') { + data = performance[activeRegion.region_type][activeRegion.block_index].data[activeRegion.panchayat_index].data; + } else { + return; + } + } else if (role === 'district') { + console.log(activeRegion); + if (activeRegion && activeRegion.region_type === 'district') { + data = performance[activeRegion.region_type][activeRegion.district_index].data; + } else if (activeRegion && activeRegion.region_type === 'block') { + data = performance[activeRegion.region_type][activeRegion.district_index].data[activeRegion.block_index].data; + } else { + return; + } + } + return data; +}; From e2e21709bf2549a492057097f0f34a8a94e2b60b Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Mon, 5 Sep 2016 16:09:22 +0530 Subject: [PATCH 241/314] Fix bug on district comparison chart --- .../performance/comparison-chart.jsx | 4 +-- assets/scripts/lib/region.js | 26 ++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/assets/scripts/components/performance/comparison-chart.jsx b/assets/scripts/components/performance/comparison-chart.jsx index b4a9d302..a5a97fcc 100644 --- a/assets/scripts/components/performance/comparison-chart.jsx +++ b/assets/scripts/components/performance/comparison-chart.jsx @@ -29,7 +29,7 @@ const ComparisonChart = React.createClass({ _this.state.active_lines.forEach(function(comparison_line, index) { - var region = Region.find(_this.props.activeRegion, _this.props.performance, comparison_line); + var region = Region.find(_this.props.config.role, _this.props.activeRegion, _this.props.performance, comparison_line); labels.push(region[comparison_line + '_name'] + ' ' + _this.props.translation.comparison.labels[comparison_line]); @@ -166,7 +166,7 @@ const ComparisonChart = React.createClass({ { this.state.comparison_lines.map(function(line, i) { - var region = Region.find(_this.props.activeRegion, _this.props.performance, line); + var region = Region.find(_this.props.config.role, _this.props.activeRegion, _this.props.performance, line); var label = region[line + '_name'] + ' ' + _this.props.translation.comparison.labels[line]; var selected = _this.state.active_lines.indexOf(line) !== -1; return ( diff --git a/assets/scripts/lib/region.js b/assets/scripts/lib/region.js index 38ce59fa..577a3233 100644 --- a/assets/scripts/lib/region.js +++ b/assets/scripts/lib/region.js @@ -49,20 +49,29 @@ exports.list = function(performance, role) { return regions; }; -exports.find = function(activeRegion, performance, comparison_line) { +exports.find = function(role, activeRegion, performance, comparison_line) { var region; - if (activeRegion.region_type === 'block' && comparison_line === 'block') { - return region = performance[activeRegion.region_type][activeRegion.block_index]; - } else if (activeRegion.region_type === 'panchayat' && comparison_line === 'panchayat') { - return region = performance[activeRegion.region_type][activeRegion.block_index].data[activeRegion.panchayat_index]; - } else { - return region = performance[comparison_line]; + if (role === 'block') { + if (activeRegion.region_type === 'block' && comparison_line === 'block') { + return region = performance[activeRegion.region_type][activeRegion.block_index]; + } else if (activeRegion.region_type === 'panchayat' && comparison_line === 'panchayat') { + return region = performance[activeRegion.region_type][activeRegion.block_index].data[activeRegion.panchayat_index]; + } else { + return region = performance[comparison_line]; + } + } else if (role === 'district') { + if (activeRegion.region_type === 'district' && comparison_line === 'district') { + return region = performance[activeRegion.region_type][activeRegion.district_index]; + } else if (activeRegion.region_type === 'block' && comparison_line === 'block') { + return region = performance[activeRegion.region_type][activeRegion.block_index].data[activeRegion.block_index]; + } else { + return region = performance[comparison_line]; + } } }; exports.overview_data = function(role, activeRegion, performance) { var data; - if (role === 'block') { if (activeRegion && activeRegion.region_type === 'block') { data = performance[activeRegion.region_type][activeRegion.block_index].data; @@ -72,7 +81,6 @@ exports.overview_data = function(role, activeRegion, performance) { return; } } else if (role === 'district') { - console.log(activeRegion); if (activeRegion && activeRegion.region_type === 'district') { data = performance[activeRegion.region_type][activeRegion.district_index].data; } else if (activeRegion && activeRegion.region_type === 'block') { From 4965a31d7b1e905e8f99ee273474ab83e0880e27 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Tue, 6 Sep 2016 11:25:16 +0530 Subject: [PATCH 242/314] Add sort feature on musters --- .../components/musters/block-group.jsx | 20 ++++++++++++++++ .../components/musters/district-group.jsx | 19 +++++++++++++++ assets/scripts/components/musters/sort.jsx | 24 +++++++++++++++++++ assets/styles/views/musters.scss | 4 ++++ 4 files changed, 67 insertions(+) create mode 100644 assets/scripts/components/musters/sort.jsx diff --git a/assets/scripts/components/musters/block-group.jsx b/assets/scripts/components/musters/block-group.jsx index b4aeb2c4..70021bef 100644 --- a/assets/scripts/components/musters/block-group.jsx +++ b/assets/scripts/components/musters/block-group.jsx @@ -2,6 +2,7 @@ import React from 'react'; import BlockCard from './block-card.jsx'; +import Sort from './sort.jsx'; const BlockGroup = React.createClass({ @@ -12,6 +13,22 @@ const BlockGroup = React.createClass({ }); this.setState({cards: updatedList}); }, + sortBy(field){ + var updatedList = this.props.data.cards; + + updatedList.sort(function (a, b) { + + if (a[field] > b[field]) { + return (typeof(a[field]) === 'number' ? -1 : 1); + } + if (a[field] < b[field]) { + return (typeof(a[field])=== 'number' ? 1 : -1); + } + return 0; + }); + + this.setState({cards: updatedList}); + }, getInitialState: function(){ return { cards: [] @@ -21,12 +38,15 @@ const BlockGroup = React.createClass({ this.setState({cards: this.props.data.cards}); }, render: function(){ + var _this = this; + var sortList = ['name', 'designation', 'current_total', 'delayed_total']; return (
    +

    {this.props.data.region_name}

    diff --git a/assets/scripts/components/musters/district-group.jsx b/assets/scripts/components/musters/district-group.jsx index 5cc622cf..c7a78ba2 100644 --- a/assets/scripts/components/musters/district-group.jsx +++ b/assets/scripts/components/musters/district-group.jsx @@ -2,6 +2,7 @@ import React from 'react'; import DistrictCard from './district-card.jsx'; +import Sort from './sort.jsx'; const BlockGroup = React.createClass({ @@ -12,6 +13,22 @@ const BlockGroup = React.createClass({ }); this.setState({cards: updatedList}); }, + sortBy(field){ + var updatedList = this.props.data.cards; + + updatedList.sort(function (a, b) { + + if (a[field] > b[field]) { + return (typeof(a[field]) === 'number' ? -1 : 1); + } + if (a[field] < b[field]) { + return (typeof(a[field])=== 'number' ? 1 : -1); + } + return 0; + }); + + this.setState({cards: updatedList}); + }, getInitialState: function(){ return { cards: [] @@ -23,11 +40,13 @@ const BlockGroup = React.createClass({ render: function(){ var _this = this; + var sortList = ['block_name', 'current_total', 'delayed_total', 'days_to_payment']; return (
    +

    {_this.props.data.region_name}

    diff --git a/assets/scripts/components/musters/sort.jsx b/assets/scripts/components/musters/sort.jsx new file mode 100644 index 00000000..e2990bfc --- /dev/null +++ b/assets/scripts/components/musters/sort.jsx @@ -0,0 +1,24 @@ +'use strict'; + +import React from 'react'; + +const Sort = React.createClass({ + sort(event){ + this.props.sortBy(event.target.value); + }, + render: function(){ + + return ( + + ); + } +}); + +export default Sort; diff --git a/assets/styles/views/musters.scss b/assets/styles/views/musters.scss index 05bd9c9d..5aaf5daf 100644 --- a/assets/styles/views/musters.scss +++ b/assets/styles/views/musters.scss @@ -58,3 +58,7 @@ .table{ width: 100%; } +.sort-bar { + margin-top: 4px; + margin-right: 10px; +} From 42df86316c3c39532bfb0074ffec491420332df9 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Tue, 6 Sep 2016 11:34:58 +0530 Subject: [PATCH 243/314] Add translation to sort By --- app/locales/en_US/v1.js | 8 +++++++- app/locales/hi/v1.js | 8 +++++++- assets/scripts/components/musters/block-group.jsx | 2 +- assets/scripts/components/musters/district-group.jsx | 2 +- assets/scripts/components/musters/sort.jsx | 6 +++--- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/app/locales/en_US/v1.js b/app/locales/en_US/v1.js index a74f1b78..91eb3199 100644 --- a/app/locales/en_US/v1.js +++ b/app/locales/en_US/v1.js @@ -26,7 +26,13 @@ module.exports = { work_name: 'WORK NAME', work_code: 'WORK CODE', closure_date: 'CLOSURE DATE', - days_pending: 'DAYS PENDING' + days_pending: 'DAYS PENDING', + current_total: 'CURRENT TOTAL', + delayed_total: 'DELAYED TOTAL', + name: 'NAME', + designation: 'DESIGNATION', + block_name: 'BLOCK NAME', + days_to_payment: 'DAYS TO PAYMENT' }, performance: { overview: { diff --git a/app/locales/hi/v1.js b/app/locales/hi/v1.js index 47e460ab..5591dd3a 100644 --- a/app/locales/hi/v1.js +++ b/app/locales/hi/v1.js @@ -25,7 +25,13 @@ module.exports = { work_name: 'कार्य नाम', work_code: 'कार्य कोड', closure_date: 'मस्टर रोल बंद होने की तिथि', - days_pending: 'DAYS PENDING' + days_pending: 'DAYS PENDING', + current_total: 'वर्तमान मस्टर्स', + delayed_total: 'विलंबित मस्टर्स', + name: 'नाम', + designation: 'पदनाम', + block_name: 'प्रखंड नाम', + days_to_payment: 'भुगतान के दिन' }, performance: { overview: { diff --git a/assets/scripts/components/musters/block-group.jsx b/assets/scripts/components/musters/block-group.jsx index 70021bef..726dc683 100644 --- a/assets/scripts/components/musters/block-group.jsx +++ b/assets/scripts/components/musters/block-group.jsx @@ -46,7 +46,7 @@ const BlockGroup = React.createClass({
    - +

    {this.props.data.region_name}

    diff --git a/assets/scripts/components/musters/district-group.jsx b/assets/scripts/components/musters/district-group.jsx index c7a78ba2..c50ee6c8 100644 --- a/assets/scripts/components/musters/district-group.jsx +++ b/assets/scripts/components/musters/district-group.jsx @@ -46,7 +46,7 @@ const BlockGroup = React.createClass({
    - +

    {_this.props.data.region_name}

    diff --git a/assets/scripts/components/musters/sort.jsx b/assets/scripts/components/musters/sort.jsx index e2990bfc..2d52ebf1 100644 --- a/assets/scripts/components/musters/sort.jsx +++ b/assets/scripts/components/musters/sort.jsx @@ -7,13 +7,13 @@ const Sort = React.createClass({ this.props.sortBy(event.target.value); }, render: function(){ - + var _this = this; return ( From ae0ab5eba3fa3d6c44f4c94e51ed07e7f0a2fc55 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Tue, 6 Sep 2016 11:48:26 +0530 Subject: [PATCH 244/314] Update overview spacing --- assets/styles/views/overview.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/styles/views/overview.scss b/assets/styles/views/overview.scss index 19fe3e32..83cea016 100644 --- a/assets/styles/views/overview.scss +++ b/assets/styles/views/overview.scss @@ -22,9 +22,9 @@ padding-bottom: 10px; font-size: 2.5em; text-transform: uppercase; - letter-spacing: .2em + letter-spacing: .1em } .overview-card-details{ font-size: 2em; - padding: 50px 0; + padding: 10px 0 70px; } From 3010c5c43238632957dbcf3c7bc8dae6239df9aa Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Tue, 6 Sep 2016 12:32:23 +0530 Subject: [PATCH 245/314] Add default region selection --- assets/scripts/components/performance/subnav.jsx | 5 ++++- assets/scripts/containers/performance.jsx | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/assets/scripts/components/performance/subnav.jsx b/assets/scripts/components/performance/subnav.jsx index 65594c17..34b5ba1f 100644 --- a/assets/scripts/components/performance/subnav.jsx +++ b/assets/scripts/components/performance/subnav.jsx @@ -18,10 +18,13 @@ const Subnav = React.createClass({ renderValue: function(option) { return {option.label}; }, - setValue (value) { + setValue: function(value) { this.setState({ value }); this.props.onRegionChange(value); }, + componentWillReceiveProps : function(nextProps){ + this.setState({ value: nextProps.defaultRegion }); + }, render: function(){ var list = Regions.list(this.props.performance, this.props.role); return ( diff --git a/assets/scripts/containers/performance.jsx b/assets/scripts/containers/performance.jsx index 80fe26e9..860e425d 100644 --- a/assets/scripts/containers/performance.jsx +++ b/assets/scripts/containers/performance.jsx @@ -5,6 +5,7 @@ import Subnav from '../components/performance/subnav.jsx'; import OverviewChart from '../components/performance/overview-chart.jsx'; import ComparisonChart from '../components/performance/comparison-chart.jsx'; +const Regions = require('../lib/region'); const D3= require('d3'); const Overview = React.createClass({ @@ -18,6 +19,7 @@ const Overview = React.createClass({ performance: json.performance, translation: json.translation, isFetching : false, + activeRegion: Regions.list(json.performance, json.config.role)[0] }); }) .on('error', function(error) { @@ -45,7 +47,7 @@ const Overview = React.createClass({ return (
    - + Date: Tue, 6 Sep 2016 16:30:05 +0530 Subject: [PATCH 246/314] Update user icon --- app/templates/partials/header.hbs | 2 +- assets/styles/layout/metabar.scss | 1 + assets/styles/views/performance.scss | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/templates/partials/header.hbs b/app/templates/partials/header.hbs index 6a973ea6..134d4d4c 100644 --- a/app/templates/partials/header.hbs +++ b/app/templates/partials/header.hbs @@ -5,7 +5,7 @@
    -
    { this.props.children } diff --git a/assets/scripts/index.js b/assets/scripts/index.js index c3aeb22c..824fb3ef 100644 --- a/assets/scripts/index.js +++ b/assets/scripts/index.js @@ -3,5 +3,8 @@ import React from 'react'; import {render} from 'react-dom'; import Musters from './components/musters.jsx'; +import ActiveLink from './lib/active-link'; + +ActiveLink.init(); render( , document.getElementById('musters')); diff --git a/assets/scripts/lib/active-link.js b/assets/scripts/lib/active-link.js new file mode 100644 index 00000000..bdd47322 --- /dev/null +++ b/assets/scripts/lib/active-link.js @@ -0,0 +1,9 @@ +'use strict'; + +const $ = require('jquery'); + +exports.init = function() { + $('a[href="' + location.pathname + '"]').addClass('active'); +}; + + diff --git a/assets/styles/base/base.scss b/assets/styles/base/base.scss index e92ce3c9..aec123c9 100644 --- a/assets/styles/base/base.scss +++ b/assets/styles/base/base.scss @@ -16,6 +16,7 @@ body { font-size: 1.5em; //Should be in sync with $fontSize-base line-height: 1.6; color: rgba($color-foreground, 1); + background-color: $color-background; font-weight: $fontWeight-thin; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; diff --git a/assets/styles/layout/metabar.scss b/assets/styles/layout/metabar.scss index 7903d4eb..681dc3dc 100644 --- a/assets/styles/layout/metabar.scss +++ b/assets/styles/layout/metabar.scss @@ -16,18 +16,18 @@ body { font-size: $fontSize-base; position: fixed; z-index: 999; - background-color: #fff; + background-color: $color-background; top: 0; left: 0; width: 100%; min-height: $metabar-height; - box-shadow: 0 0 1px rgba(0, 0, 0, .15); + box-shadow: 0 0 1px rgba($color-foreground, .15); @extend %clearfix; } .metabar .brand { letter-spacing: 0.35em; font-size: 15px; - color: #00bff3; + color: $color-accent; text-transform: uppercase; padding: 16px 40px 15px 20px; font-weight: 500; diff --git a/assets/styles/modules/modal.scss b/assets/styles/modules/modal.scss index 9bc7e084..35ea82f4 100644 --- a/assets/styles/modules/modal.scss +++ b/assets/styles/modules/modal.scss @@ -1,19 +1,20 @@ .modal-wrapper{ position: fixed; - top: 60px; + top: 62px; left: 0; height: 100%; width: 100%; - z-index: 1000 + z-index: 1000; + padding-top:60px; + background-color: rgba($color-background, .95); } .modal-item { - background: #fff; + background: $color-background; padding: 30px; - box-shadow: 0 1px 4px rgba(0,0,0,.04); - border: 1px solid rgba(0,0,0,.09); + box-shadow: 0 1px 4px rgba($color-foreground,.04); + border: 1px solid rgba($color-foreground,.09); border-radius: 4px; max-height: 80%; - margin-top: 10px; overflow-y: scroll } .muster-table{ diff --git a/assets/styles/scales/color.scss b/assets/styles/scales/color.scss index 8c6872ce..5df06a78 100644 --- a/assets/styles/scales/color.scss +++ b/assets/styles/scales/color.scss @@ -7,8 +7,15 @@ You should never define any color outside this file. $color-brand: rgb(30, 44, 79); $color-accent: rgb(51, 195, 240); -$color-foreground: rgb(0, 0, 0); -$color-background: rgb(255, 255, 255); + +// Theme Light +// $color-foreground: rgb(0, 0, 0); +// $color-background: rgb(255, 255, 255); + +// Theme Dark +$color-foreground: rgb(255, 255, 255); +$color-background: rgb(30, 44, 79); + /* Brand Shades ---------------------------------------------*/ diff --git a/assets/styles/views/musters.scss b/assets/styles/views/musters.scss index 9379beee..11a93cb7 100644 --- a/assets/styles/views/musters.scss +++ b/assets/styles/views/musters.scss @@ -11,8 +11,8 @@ } .card { min-height: 300px; - box-shadow: 0 1px 4px rgba(0,0,0,.04); - border: 1px solid rgba(0,0,0,.09); + box-shadow: 0 1px 4px rgba($color-foreground,.04); + border: 1px solid rgba($color-foreground,.09); border-radius: 4px; margin: 10px; padding: 20px; From ebb4b91d3f1b4aa0ac87d3145a06a68639c9ecb7 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 18 Aug 2016 11:55:38 +0530 Subject: [PATCH 139/314] Cleanup --- app/controllers/api/cards.js | 2 +- app/templates/homepage.hbs | 2 +- assets/images/logo.png | Bin 0 -> 60093 bytes 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 assets/images/logo.png diff --git a/app/controllers/api/cards.js b/app/controllers/api/cards.js index b39cf23b..02582459 100644 --- a/app/controllers/api/cards.js +++ b/app/controllers/api/cards.js @@ -17,7 +17,7 @@ exports.getData = { handler: function(request, reply) { if (!request.auth.isAuthenticated) { - return Boom.forbidden('You are not logged in'); + return reply(Boom.forbidden('You are not logged in')); } var sequelize = request.server.plugins.sequelize.db.sequelize; diff --git a/app/templates/homepage.hbs b/app/templates/homepage.hbs index 504d7249..b0974f49 100644 --- a/app/templates/homepage.hbs +++ b/app/templates/homepage.hbs @@ -2,7 +2,7 @@
    diff --git a/assets/images/logo.png b/assets/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..91590f9147bbf2e142c81b241c76153fa427fd81 GIT binary patch literal 60093 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Π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 Date: Thu, 18 Aug 2016 16:05:10 -0400 Subject: [PATCH 140/314] Add translations for district version of paydroid --- app/locales/en_US/index.js | 23 +++++++++++++++++++++++ app/locales/hi/index.js | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/app/locales/en_US/index.js b/app/locales/en_US/index.js index 5fc388c2..c388444a 100644 --- a/app/locales/en_US/index.js +++ b/app/locales/en_US/index.js @@ -162,6 +162,7 @@ module.exports = { } }, app: { + paydash: 'PayDash', overview: { musters_closing_today: 'Musters closing today', delayed_musters: 'Delayed musters', @@ -181,6 +182,28 @@ module.exports = { closure_date: 'Closure date', days_delayed: 'Days delayed' }, + district: { + overview: { + view_your_blocks: 'View your blocks\' performance', + show_blocks: 'SHOW BLOCKS', + days_to_payment: 'Days to payment in last 3 months', + musters_closing_today: 'Musters closing today', + delayed_musters: 'Delayed musters', + }, + cards: { + days_to_payment: 'Days to payment in last 3 months', + musters_closing_today: 'Musters closing today', + delayed_musters: 'Delayed musters', + musters_diff_steps: 'Musters delayed at different steps', + avg_days_pending: 'Avg. days pending', + total: 'Total', + t_2: 'Attendance not filled (T+2)', + t_5: 'Measurement book not filled (T+5)', + t_6: 'Wagelist not sent (T+6)', + t_7: 'Pending for FTO first signature (T+7)', + t_8: 'Pending for FTO second signature (T+8)' + } + } chart: { days_to_complete_process: 'Days to complete process', steps: { diff --git a/app/locales/hi/index.js b/app/locales/hi/index.js index 5992f6de..38b86dee 100644 --- a/app/locales/hi/index.js +++ b/app/locales/hi/index.js @@ -166,6 +166,7 @@ module.exports = { } }, app: { + paydash: 'पे-डॅश', overview: { musters_closing_today: 'आज बंद हो रहे मस्टर्स', delayed_musters: 'विलंबित मस्टर्स', @@ -185,6 +186,28 @@ module.exports = { closure_date: 'मस्टर रोल बंद होने की तिथि', days_delayed: 'विलंब(दिन)' }, + district: { + overview: { + view_your_blocks: 'अपने जनपदों/प्रखंडों का प्रदर्शन देखें', + show_blocks: 'SHOW BLOCKS', + days_to_payment: 'पिछले 3 महीनों में भुगतान के लिए दिन', + musters_closing_today: 'आज बंद हो रहे मस्टर्स', + delayed_musters: 'विलंबित मस्टर्स', + }, + cards: { + days_to_payment: 'पिछले 3 महीनों में भुगतान के लिए दिन', + musters_closing_today: 'आज बंद हो रहे मस्टर्स', + delayed_musters: 'विलंबित मस्टर्स', + musters_diff_steps: 'विभिन्न पड़ावों पर विलंबित मस्टर रोल', + avg_days_pending: 'औसत विलंब', + total: 'कुल मस्टर रोल', + t_2: 'अटेंडेन्स नहीं भरी गयी (T+2)', + t_5: 'MB नहीं भरी गयी (T+5)', + t_6: 'वेज लिस्ट नहीं भेजी गयी (T+6)', + t_7: 'FTO पर पहला हस्ताक्षर नहीं हुआ (T+7)', + t_8: 'FTO पर दूसरा हस्ताक्षर नहीं हुआ (T+8)' + } + } chart: { days_to_complete_process: 'प्रक्रिया पूरी करने में लगे दिन', steps: { From b72956578030d6e0dfb98f5f69b12d913f4dae8a Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Thu, 18 Aug 2016 16:59:21 -0400 Subject: [PATCH 141/314] Exclude unmapped card if no musters --- app/helpers/queries.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/queries.js b/app/helpers/queries.js index 7f0a9a7c..8ce7a746 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -42,7 +42,7 @@ exports.paydroid = function(USER_ID,ROLE,VERSION) { } else if (VERSION===2) { if (ROLE==='block') { return "SELECT a.current_total, b.delayed_total, c.days_to_payment FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment, 1 AS merge FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + - "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + + "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) WHERE a.staff_id IS NOT NULL OR (a.staff_id IS NULL AND (c.current_total>0 OR d.delayed_total>0)) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + "SELECT block_code, block_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc, ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;" + "SELECT block_code, panchayat_code, panchayat_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc, ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), panchayat_code ORDER BY panchayat_code, date;" + "SELECT state_code FROM blocks WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY state_code;" + From 7311cd11750a3ddb119975732f9243aa802fd004 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Thu, 18 Aug 2016 17:04:00 -0400 Subject: [PATCH 142/314] Forgot comma in locales --- app/locales/en_US/index.js | 4 ++-- app/locales/hi/index.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/locales/en_US/index.js b/app/locales/en_US/index.js index c388444a..20eee41c 100644 --- a/app/locales/en_US/index.js +++ b/app/locales/en_US/index.js @@ -188,7 +188,7 @@ module.exports = { show_blocks: 'SHOW BLOCKS', days_to_payment: 'Days to payment in last 3 months', musters_closing_today: 'Musters closing today', - delayed_musters: 'Delayed musters', + delayed_musters: 'Delayed musters' }, cards: { days_to_payment: 'Days to payment in last 3 months', @@ -203,7 +203,7 @@ module.exports = { t_7: 'Pending for FTO first signature (T+7)', t_8: 'Pending for FTO second signature (T+8)' } - } + }, chart: { days_to_complete_process: 'Days to complete process', steps: { diff --git a/app/locales/hi/index.js b/app/locales/hi/index.js index 38b86dee..1ae6780b 100644 --- a/app/locales/hi/index.js +++ b/app/locales/hi/index.js @@ -192,7 +192,7 @@ module.exports = { show_blocks: 'SHOW BLOCKS', days_to_payment: 'पिछले 3 महीनों में भुगतान के लिए दिन', musters_closing_today: 'आज बंद हो रहे मस्टर्स', - delayed_musters: 'विलंबित मस्टर्स', + delayed_musters: 'विलंबित मस्टर्स' }, cards: { days_to_payment: 'पिछले 3 महीनों में भुगतान के लिए दिन', @@ -207,7 +207,7 @@ module.exports = { t_7: 'FTO पर पहला हस्ताक्षर नहीं हुआ (T+7)', t_8: 'FTO पर दूसरा हस्ताक्षर नहीं हुआ (T+8)' } - } + }, chart: { days_to_complete_process: 'प्रक्रिया पूरी करने में लगे दिन', steps: { From 827b04371398a8d705921523a57c96a227a836ce Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 18 Aug 2016 11:59:18 +0530 Subject: [PATCH 143/314] Add inverse logo --- assets/images/logo.png | Bin 60093 -> 98218 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/assets/images/logo.png b/assets/images/logo.png index 91590f9147bbf2e142c81b241c76153fa427fd81..26260c3bc0afb6554185349b1be3a64ed6f08e81 100644 GIT binary patch literal 98218 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%0A6dsp0rkEakLv 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 literal 60093 zcmaI7bzD|aw>7GCH`3kR-Q6A1-JR0?(A}L4Bk+>Z^U`v) z@$xbEuzn?B0e1a!z&*9yWFXHV$?cb`C)fc0o>d^8fmx1XuI0vJupj zmi@15fxkp3?Yz9)1libpe0*4axL931Y}q&j1O(XFIoUWlS->7Fo_;P~=DsX0o>c#R z25DYu5RQ~QvVq>a(WeWOM91>jST-eN<~Fb!Nt?d+{MybL0W_ooQKuk z-bzqPfR~$}OGcJQnv0!-Lxz`MR)$@IgGYvwms5aCR)FunkCk?{^mev(@%ry$t^Vg& zS@!?+*p~_6>;|qZZS7(I&e}@W!_}GmKMyWw|G(dh^#6Lk|2o#{f4vtOng8`zHgGd+ zFR%Ci^}7Fi6PQCUzy8nU1%Ld{^tW~abKV0?Zk$}0?pLpNm=vTXw0##23lZBBFRz~Y zC_S*>e%Oey8qM(2jgm|i%4IsE`EMyC>*$3=(s!n=oLK;U`9eHT(qr6^>+aw!-$j zaq4+PpJayo)eIR&?qxe{9Mzw2mOoGfnBWtquyq9R$^Y_U_Vzm&H{|f2e>)$}e$3uq z{rlmu+8yTT^KT*Z;O2D0Ub9LyXmgaQ;X!BPMC|D_IY__BYTl$oJPf+$FA}&KO@#AW zZ={Uq^TWBKCfWcRiC_kY^TL;|TK&(Jih~IR*TllU>@(gg72nF4`GK3pt{%|#Hw2-+X3whvJyt_PL8ZQ>>8d&R#=5kv6%3=^l;WdE!7Lr6F z^ad-9zp)D^x{5sb@$#*jKnZ>vF4NbmZwK{@tTbs7id4T`yB@QGpPwFcy_f7L(zNOE zlH7mkyp4pYwp$|QLc}RE8Fljf7oA&Fex}n+>{H6b9U>OVm+*)Gqg)idS>TY;j@v z;f=S z8_r;uAytQD3?8LFZhzFNxk)ULWFY9e-OiU3dUrVd!xec1M^Zpx#J4M#(^^rD;cxK$ zKV%{vhl{{MLGL#(YRu}yJ?~zB74Y27Fm19@=&=5g^|uB5D4>UjnZ^XIbQB4Et83l>byS^QqvgTeC6)-`?D%++2l0`52w|5 zfuB!@|K)bU#CfrRrwt85YZ~$!X1l8?IWk;{*v;WoD(bDZT&|z_e8q&qTjK68iz`bp z4rXx5#iAV>{ju1Vn8AqOt6;?6fO|!hk&}zIGJv>rT!{yoenLj5PQuA-Ig^gO``T+(^%F73=lDK@AZwy{PSXz9GNBU2Q({HeY zpKfi(l0`W+l1_vprP1)%Oadh$k#KoUYv&&B4jSeRzu0L=8GHWy``ssCRBij$0z6sZ z$)0Q?;ZFn`88E3>5Us-6PHr}m*`^L25YTM~c;<{Y7-FGdkyf=YQecCTd5ds6p#pIr za;Jt)e?IkeYCVh#9UD0hJ+H^J#YB};e=E~@Y*mI_IR38vpr|b!N0+X9Ydf0BbiEbX ziO$)l`M4wYyhkZBZHUAza*WHQ>tyQWKf`$Zo~}@$lNVS@5%M|u)#kCaFWahB^Uk(3)9dzZOKI}H=F9Qxpm&Fw z9cr4y-ljp9zh09C-ache|l{8^|{E50|D#s!J8^^gxyVq@yP9C})B46U&Lzvj89 zP7sij84OxS&XXlQ%!_K3(r-#*9vC#s`B^=w3vs$19`CQCd0m&6+znLOV0>9P2wR!rK}CtEojmPl@oJ+(+UL)PC*5#Ue>FYXcuxE##Vx*K*^y2L7n z;)!^j==nUi$C?iL{LVIWybpfsWY~LX)Bf1m3_qOzOeX{_=riABZHvodFl%WxUMSRp zfiMO&)#%}PCl>mAUqdHKiPkIJvN84pyAPosn)IoF~a8$;&B+7^m;|*lH-LyDR1H?O_CH6hK}Fa2Ll2|-{1Y)0zu>&%psTb zQs->Hh@AFg_caf!_cMbMwVNb#N@YKz(Go(mA0XUNCwGee zp#?qc*EB3MZG9?y#$(n~_xO>;GEk23ZrS4p%a0Mf)U;u*i`}U&oW`1SA9WlV?lE&Q zzOc!`L|TS3v(6pr^tNh#vn(g(3Kci;+sce?ZRn}JCvydbxZwNg?)&6U)-^ezXv1a) z+~DiKK1@l3JRf0;f9CPjlqqMsG&VMxm!`U074FScy$w45$>+H64CbW{V=i0s#>R%> zw;|g7)n^ez4Z6{?7Kiv=H@i_8w8GrLy4m$eNxRGOa^yn%V%0E7JwetML z7j(J*3mubk;PnESz-1JFUBT3CMi)Nm77oM)v1N%yCTb*agBWXFDE4?Uv*2=u$8Lo5 zzDivNt~7Qkk%;dJ8BezCc`n%*n)`2a8XaJSS3<-3|9=KP3OE*02<~U-Cbwi)PfVz2Vg_ zKjHB;2FWG)R{4_8qmMzwlr(2?s{4##^&{pwgA_U+NYHVXh2+L-gg zCEGHjKG}ZniM0p8M_DlO4bL!go7C~or?px$UAW3o8IjNtP#uv>J%947ffoMEA52w(8s;h#aJY}TLg zx1R%VJtmyi8c5jM&?s68GMU~k_j`5jf2`>R$t($dd;6B8N9Be{YVtXKLt6S;O2 z!5MyxAsqiq1PUKv4zKgVC*}T6$~m#p@5Ar0=#%0dgu%Ocw2FhwRH>1<%r{lo+P;TT zN2}+;Ufc1WC=!8B!sjUCX*jjc>EoWx0l>gHS4iak`grC1U&~7U)$LBP?biv>r<;wX z&$bh+u1NGB8eRT=OL!O$IPQ2$o2GT?K_YGZbUP8^KOtkYPB=;fcg~|uj5pxBoojn% zGn_&(wtux6fv&nEqT5obl0R z+DxTN&314UA`D;ubEm0(;7Jd>4E_ki=sKBje3SK$qgRMo%=%~d;(jo38{z1^AH>ZA z3E4VtEaa90&PM3qcP5ITtC?zVC|?o~G>&G4Vx|fLS7&m&-}%##*!J$!`+Sl6!_OTc zW3Snlpj>l3;L+nqwxy24b8`T|fv;+4s?IhQisFL3_fJEwZFV-P&llf^WC7 zYiQVqhNEZ-mmiB#lw`5iRdwE8Xs*Z;j)91=$Y04Sk*ZsGR~N{skY@ zW~t}nwZ#)5)v(p`?Vn7D{;%!j{j7M45%1;BteuuxIUd2Qo2K2dodct|2Wk~Um2xiU zp$|Je6}!&(B0jrWcRB%=%|-hq7(qlw$|&nRcEmocb#}}YFmdao?N^J%TW^adWogcB zaafIRFt+1KxIWk+Xb?<~8pB2)O8&ux-Mr%h?=@}iIp}K5M?<^k^Zhe)MG&Z%{&B@I zN^WXU+q-^$p8(vQwOeXEHNvVn+x{64I9shDV>_19s5&`UbDGPj^Ko61{9if0?9{1p zc<@0Vx|ne6@v{36i7Ch>BJW{xyC`#=uMX!c((XtC3BLOrj~4=v_H*#6pE&G7#)C+~ z5of>c>F%HfaZkDyBWao(J1a0V@b-)Zt!UXaw-UsdKXQ}a(Ndd_Vw(-}k)qkhg7YxM zZbq6djC$kmS5@1@g#dW^g1Wl~szRi@)4~&ppclR+eW-d#E|XLg%APOhglJ|rhv8SJ zd91-N-7v3tLXG%kH8HU=P=|iCNz=(dQ4wMb{}4<5e%u+5nc>bamqfg_iSrRnIrF)v z+sY2)tw1lP1oa1GH$Fz~>Q5@YBp{4rZcc~DlKGNgRaJ-05IC6C=8oMt$)IfzCB?k= zXW6%5X_YlGajt!(?b0-n{+v=zNstDBq1|s2#&~w?8yc}UGdOcP?zmpImaYpIAfr$6 zTm8q!hXe zcqV-pb?Ey-c&2m(Uzu&w+ zTnaRs^@Q64l-86r0g(Q+8wl~8OnMCq)(^*=e3i*WeD!F>i6lZ_=K(UD0qv`Qk@~RR zb?co;F0p_|?HtS_<~~1)?ReAJeq`B-4}Nw^xz9;873e!L628mqSQ| z9X*mxoZArNdJu5r(xAhr7jeH#fnsrz@7hU_l$3;)Ou#j`VZZ7fa@aT|OYrR_g*ZtT z4pyzQ$#-8mV!-ySgt~pF&@Ut4=R%z#zq!gi$QRe>IqeQp%&Ll)(wQ2mlFNcXE!YmY~NzoWZ*vNAIl%&sn(f4Y05CZ|@{I2ltD z$w7wLOL&cRa9ftAa=M{MOLEE;3AwF?`bgQm`U_fKen&Iuyt^N4UBX{L&maFYw?H)L z4m%P88tc|$(1NZoW^n!njc>>GsM0+5=K@^QBPF~uwb5+0=Pkgdq&l3e_WbiBgQ4u7 zay$54_q`myvuZ>Wz%f&5O38g;QQSaQ&~4{xHkfn>JjI~y$|!!|eMTqb-sKUTSpmQ~ zWb~~C=(Y@J26q}x6K8g<7x28ef)#iOsKVHftN)HKQ8Dj`x?U);{Sxnj`l3br? zABAGZKu#Y2go*E3Bx`CCbZ-fSJSN<-4B_Fv`?h2^xfFk{xW^S-*gjrHJ^{|SO0|%N zU(+~>?g<|Q?E%xt10zMoh24}=!b$mq{Omq?_SU8m-VKQXaWLwUT=&M!%o{Q?u}wf| zmG1wliH1N)Mx&FFR$Lo|fYcIsb-WVtuUg|h3@_4gq#;G5dJC8fRDX{*T>rFr+Aafv zh?lJ$g;47Lt-lnG=Bv+%RO|o{S0z5bmc(rO&|x=KCj8KF9sk93C7AjN4QYzodEtTp zBSkqk>x*47l2xYi}il3#V4la@g zjUO%a^S=;JJ&XDqPc4w5ueiFbpS28Ur}s33AxZo??w)(Wx038J(=3)Uj?9$-OYw-1^?*2o)$)WaZ&m^K;wluVfIDHrexd<${KTGqZ zw#(kZA;nqF{A0ml>#MU+wflAVg<8gLe zjsrS|V6dSF35{pzOre%Fnjuy`(of!A&OX#ke(LHu>C%{^C`t#VZ^islC=QS9iApBi zH?id24_YOUJJ-2^Ln-Ye?V#WH;FR)jt;LL@_!6(h#|C{=6QxrJ=77BtCr5fG3Wskkh8&-7~ek+xe$Du9alU$6-fx}pC zb9>BKwL$9-XM&pUgv#|LDW~)3MbSEFfJ^2irsm{$ed3za9S(=#HU_^RO^CbHfI^x1 z_gt&ZJd{u~O!3I(7nC(@Mlp7*-5UW2qg+fG;HjU&!o0)QTTr z0v8ee$=TKqSIcGU9e>)9voZxns#FFrGUk+|SE8M$56HDA2o+uOpOnzyzZ#UoMpr3G z?Qn5A{0pI^+K%ZDEV23vLB#HzC4luV2`vhFx}|&EnFl;`Zr0ahGI~la!6SbCCq?la zK|af+R(I6cCTd$b`=)j~!5`KTqellxlallM)vJ5aMzPrj8vBeUw2o(OoZ{l})KCss|Qy2WP4>(-=>QD;Pjtwzw# zXT`?FE%*Z-O?A>6)){T${A!pg*{cxLJ;%TINzRL3gO>c)V8*6?c%|H_-r&;GwZl`Q zki&Uetmk*ng?X?SLzf!P!H}aklr!HDXGM;ReiA20H6YfmGq^+^Bf^*f^itoO%TGtn zB_w4`Pr`VVLcZq`!Y+}X2u3%$;w-5imZ}4mh$($5MC9Vq!!%HEF&mtJgYWjL=;y0S zLEBtLeTR4#ty!sjOF0}mA%Ud{v$fYL>jGa84NycSEb56LV6Kapv?|BGTeX~tHA{`C zNUZWXFKC~EHb{87*>NtKl83Ld#t^iOzki_Id4T5PgLiG!s$u`YK;jgVuF1~3u3+1` zI+LafA}vGh9sNX`U+p{5+ z=t0kq*Yo*++0jvC!EIyk${VVMdIPvCzaR@NLrWY5K%(E9+1!Ri9EYoybkljGbI%)2 z>T+T{c6DiNi;t4b>P@KFp(tnmaGKnImDi@x7@KiY!of#Bv9nFtJ?kYjc0VG{x)Wg+ znMvT~nE0(7xkf-yJ38oRKLr~sR<0pGLevL$CFTmUfp<-$%={*|q~%}AuX+%jl>e9& zZ2>>^qwno}HpKF8l!7!5 z!e^{R_uQ%i=+Pffa+3`HPEOi^bXKi|xyTh!&(LXaHA{7IV7HDaGZ`+>TT-<_9L2=O z>PvPQyqyBbpOa9%Q-j!z-)_b3mhrgr-X*6UEqgOk{JXgh5k{jp18XYM8ZT$c0S=8e zz_)|NCGafc8sLF=odK4|(;t3gTa`NCHjZ`FY*6_WMwLC{Fnd{^wq{ge?#wii@r;>} zj`v_r8m0%mvuoX|p^Cl&N3)hhCe|sx-D{3`!Nae_gVcyl+Yh9pvwr|ySH6aZ^LmH$ z^o8|p{gM!m!>k_b`TMl7LhQ9kv8Nj<>w2R$T^d30>~CH3B@)mRVv_h@#lxTw@BU^8 z%2s@JUVLKRf_Ri@o1061C5OvpW&!DC3WGE@Ln{JcwXbp7IPx314`ivM*ao|EKL7MV zF!((HbY^_mS)B9bt&&?nbc(v~=H#z9{Hw{z&=kXk5r)I$MXj-FXzQ@WvmHPux^fwIBTC^gqsDfkU z(NfBwZxmI3ZQHUnlD-qOJ*A6LHa5tsNo*WZJ!<_0lQEMVJMFJYyYDHfB#sFKKcX7l z0vE5tY_-_4Qup9+e~xu;q~-_HuFkjQIqEDFIzrnoQeU|A(h9{RDOnutDfSZ16 z8tzs2j?z(6Pad`g{radgx1N~Y?ym4UBO5U_?^=I^RwZvXee#oX z?kVw1NRZVI62YTkoO4zUH~A+-`+x7QX(Xw&XZErTUG$SE$MX4(Q^jEm9;3=s(`ivB z_BuD+I!2J()w{R=txVlYvb)^zea^=ptfTy67vCl0nF-C6RDM`IZRyK%S@68 zqzwehS`EY{U5E5M3~abeg*0>;FCcPVaK3if{E^MplWP?1)qYWD(2NB17M~1wqx$D~ zjy+`ph0wP%`B`&<9RWpi>uDkym54VG z@UK39o;kyiUL?A|`@idi`d74g|BQ<=*VGMwIq5+ceW3C#W&0vW|0vWQrV-9BEVhca$jUR;?=CZ}53;`Dt2pf~+WxX1qv7AO>piXdbR>n*=>HgyrM;j6^+#pb@?**n;`Y{Lsg%(EdEpJqu48yNkQD+Mi!m=lz2n>*Doj#h(6DaM zE?AL;86 zvsVO$Y9O*M3!lvU7%}2Aev^B)jxG^|wUuS3S0}K3{%`@*o2Rm8K{~Y}Vydll)9rB! z;;si)d57P%`pz%3`vg#M`PU^ypp{v1@EQcV}lya>9Ol9NN;&JF~0&z%Eo14HSLu#i_0>EdM652Mo0$05&# zHsb{X1ON0iaXK`pQ3<*6$!Fbqi^*H>HcKQTNH=(xH6YEwk9QFmCd*3l@~sE)Y@G;* zg%F_j&gK3_Mi;r5M5Ln|p8y2I9J6lipJ-0~H+HZ>Qz!_EpLIXy_$>R`l4@TAHtSyP zADVnmHh~U0He^sqQgZ_mvye_6ZT|~k8QbxpAQ^o{ilyWxz{edj7hbD&P1pi;Lq}W_ zh)W|^paIp!Nkb+PddEz1{az;iO^4MqN$2cN_I3|(X;&~Z9;?$QpjFjpd#)QcX%a(J zV4pkSQ6ldFuo32TTkWPpObzFz)=M1wKwrxC3>34fL4r7RN%;-wDqfh>E+A+8TiW=c zyvOkR<9FZF^_Ek8gv9>2nzwAY=31h39^q{iFdSPE=%RMMD?!(ZC($aGkNCP4{*}YE zaakqSYTEo$kkHuf)!hsWfwe=3cN|;PZcJhN)4R6qJjW|}%qy4=pgLRZw6$m7D0n50 zuGLH(A7)bG*WPQtstD`NSg&JVYs)Mk6#T95K|7<2`jF(?S`?8aV2UXyI#t2^?;{}j z87y5?z8d^%g}dPX*IUy^E>X(r>rJ%1Kc2^cYmWcjzP_X$V}M`gRj2=|0L%rHuRy?X znxked21EK2XG9;U_dE;<&dRfw2Xom(oL2Hgp1fFvlMavgqR6GGQQ$pX7ZgZSVbJjPG-=ddQe^eW)>R-~cwyv`en1u3gc~MBu-B55u13YJB|W;u9;0ww=h))% z*I|@u6dLCCoFbp=$Wq~LA_|a z$+a!o3saK{PZ6A&triJ>xUq%3b^Us5|4V4i%j%NrJF%zi=*~C@U;au!%5lN8Rke1} z^{21^+SW&Y&noO-3XD_BsTeta3I1a8a1zE(-v{b$|H+8uqHNy;yR?{wLnZZh!kat^k+ z%y#yify&xIcH&q;q<90;DG~Xi>%m^;4r}MX-_b;g1U?QQ0cQr`Wk1gO>Y|EFJ~5^e zh((R=`8)d8y5_`b2!g_KK>QWM!p8oba*QERy7tAeUoPFUMmYyX5)VB+Nev=XV~(1O zkL%{aVioF?BCoW%_K^xjjiMkJK~(!Z zl}Zlnw1t$q))3S#L`gPiqfXiKL??Y^q`K9R95qNDDONWn{U>1K$nK{OMWKWFLU^7~ z`G=FHQ^H&_rH}dc@bkp)J$~}~6wx6(?CH)NlA*|tnhFxZet^DK+X|MBJ1R(4K^D)z zP?4e3%gJi5I)CI3d3s=KvYmK>-Tn!3l@ifU`pJZ&`Geq@6C>9YSe}XBn}Eq}#aYCC zi7Z~hLPQFyIT!<0iOxAjYtT8ktb}QH(g%f@;t;8l`r7HS>tclNJ zUaEMC^4YRaH0bGeM~Ex8B9PwS$dGoz`AVQet^wG42(g+FA(G}LqG!WYj@c}RSrG*U z)2CrelCbm5n$9y09a`J!QgtRQZ4GOS%gK~87&u4P$ZxBXXO^bkuq0f{?XdZ(34mQ%=W^;MzZ-P;! zg_L#bp^p+VG;MO#gvz@^Qm2Lkr}^7KIkyrzJ_0?5de6`8JF)a2 zQ>c|U0c5+V2kF;iwxMJ&S~0&2Q|>MS_825sFuOnLLyrd%RXxtP;h*JwJ`^-sGNXqi zh_^vGtT!fB_d9a}Ut^M!C#oiR-<#2@7W{!XMXsiudeBdv=vnc~i)GcSAd&I+s?$>4 zmhVsI0t!Ml;2rPRKlFYko=cf+Tju|ovGd41Gg#i+5OFq8MYZ|qAuvM%(j6^^Xv12G zKE)Bp#9yqBe=@K-Az_Xr)4>w?8TF#qBCLTX=Pv}6V7P^ZD>(iEQr z(Mbd^tmp4Fuom{Is}wjcyAgNmuV$Sv$`mB}BZ%Lq%)X~bE<@8aO4bxds30G}R{E!I z_;bWTMuXiwu~rtYA%GPJyVpJT6OY}b+3&rjWV+%&j~MmYzVNg1JJ+oi{SUC$Z{;;= zEp*;V4TSjgHKJfe@Fth_`#|kTY#XQ%f5ciAL140pgtX-7UVY#X)?cHTL!@xpAq_1v zvT|#5236wO?CIfFCjj)9x7xww;_gP9L`;SsG%J!E*3EhQF<(!8Y&>fmBE8pRl0v&m zog|609@$6ho7S~3pp}-B3)#b?gh6k@d&eURgZS6$u>%>NMBQ*(jgPh+V#YTGqgPVv z05Ruzv*2zPf%FsQ1zh}IrYZ~b#4<(N9@SD4;n99Clwv@ua||powi4Z;%Q$?4zh8U{ zrsbSDBpaX{(?{vAoiUoVtuKC}7U6Y(sO#x71@SQaFgjt;)32bH8-*cq(x`QJ4IE@5_+y21%7V38n=>S z9!IjHnRspA7?Va>zcACWZz&&(JWC|&5W-KEz=OJ$BLtiwns&@-C!l19@VPD*>>qtU zHgUFMrDSvy1dQj`q!R{e1_*M)%}a}~0cCV|veuVN{UyjK`aMh#{UjkH|M6P>q}BWt z$Q6H4!pY;vdkkYmSY9j08KXi7_XTigS-K+C_pVn$im_XjwPC}cWs#e?VQ@9(ji9t; zk-`s`Qy?5xI@6JHZg5dv%xb$A`Wk_p5KBzPg3nga>1_;=pLLN~l5_%IY-i?E9!2B{ zV5$zftH|nkm=^!*pbhWy-ZM$=Wea5>&ktd3HmN|dm8g%8i@Vbt4J;bBCRmXQ+kH6L z$PcR>3dlh%L7BubB2tb46`yRQJ=Se4V)f6r30Mx?%Q0TdBctKAsOdQoF-X%4mjdR0 zBI8>dEdypU(i_G;C!o9!nd$!S1jN>A2VIe`MJuEwEkh>AGbvXr%%I3B6Dd)6zkUIm zPPKLs+@rmLvEvBwXkxO&?p6RreB$~`O&SIp>61AZxmp1G3^dp*nq3)scygH(UAs8pxLW?8(ux^$$Rh*^sZ{*re%FY@xgDd% z=^`a~@w=_2UixtHl%Gk>fvN%-0mSI~40{p=llF*W%`n4UGqdyOUV+gzVI8*BI@&B0 zmwd=~z^z~{fB6_i!Kh#lwDzQkvlml}DlgTtt3!xliHAe;^(u|G^l79Ka5Hrwen`(nFI%`) zre(+7eoeGEqomA<+(PI(`SW6tfOiBKXrm}IKox^#DuqSDFlX#QEi0o8p#MYZvgE_C zkO785 zcA9;Rj#LW+D6#H>6lrxmfblSl8#nIw^lEN6hF1sH{J)8aj8*k|&Uwoq%J7tn^aCry zQlC0bsR6^!TR^pJ+8{8cpnJRS*In6E(WuX*kfa%rV~{}t~H%|QZtRV9qt^T zKqL59@kn56=Da>vhYEtFg)k((*l=ijkZdY5kds=KIT3?te-_IA0xs*lsMr&bhj=I~ zGjZXb#l5_^b6ei$bK7&?_rR0E{8j%Foe?yF(%nFA-c9bvtb_r51R(Nh8>MFe4aFE(d-0hMiwc z2?BC#)|zMPhuOkB3eC{vZUQD4Tr5gtfbAxf-arJ=yC|ynQZFiZnvAc-gcP4V9Dn52 z;=sphL2gQvH*kKvk)v-04SDmYM?_=FYS6s?QIX>*MPw5xa-+4skVI`31%wqX4wNK< z^}(}5OqN8S14+YY-F@L4X;94VsmzU-t$!KX$mavsvvN86DKG)M<9ux_K&sm}Hm{$) z#?_Kh+!f8`sChA-c+tE@cM#Nwb((K-E*nOtSeWTBx%!m@vle?-btm*HnvTM%x9vn! zU7Vek%XVBC%#sW{6NZm_z#DLpHd~G_q7^rn!+`ZFW1lLATT;en&8H_i{m{RvXz({c zkh=ck=hh4LGa?41hm_eC^?siLWQ{b<(pc(oYCDRT!5r*CigEDi%C z5iX4N)kKH7o*$3jiTmZgK~C@qGnFVNsn-9zZ3iRYkPP6Dc?QOacF+|%{iGyA%7DB< zUx7aIx1Jq}^ba-4un5LK)uqWXWq}S4w{ht8i110v8+CC+fMPQivBEu~eg}P0Ni!IO zA~F%B;~`xQD!O5E_|3=8zU;~4?XX4#er+;Wz~kJTGbH^h!Canc)(!+z(~l*u85M5< zwg)z8L#PT&znKF4UZX{zeZJ{p+fQ3b(|V47u?4}PrX1R!W+UWkWX2i3SRA98DWm@; zIe8iX0DdXG$@Z@ua%#9^xSevwnmsqx+@W7ZnO{Qm4MpS$u;eY~2i+!g(%gu>c;Wx! ztlJn&bd(?Bm3U5z{cu`DZkUYot$WHlQC5ZcZJdofph(c%jXYdlj2Q|@)XX^8mG(GE zMtS0eBah^yN{=h}=>m z-Amjy^g3M&&5nF;p<1+RLcYK-IRf?MoeoeNZpU)Del(%0$}$vZB7D|8vxHccHXGV7 zZ6gL_FYxq6Q6nb7P2%8yNV0)yK=kfS>tCUuc5etE@%nf?Q#C=^#DAeC^Sg94#OWYmyIzDWM9d zs#Yu0fr~q{8*ot>z5tF+dgQRtPPH%4=4pk5b(us>v-QB7TpmjPGS>KkD7Al7@_7p> zWuVM!7J4I*g%kuJ%I+zvG}u;2N!~mePWw^o?@M;sJKw~eofMVA4jUH-UFmaYI7oix zr#uaiKOv)1P>!=kjr6<_qIjS#Auh-RGS*cF{9IN_N{arjjWNIo*`6Yke?LG&%_9%d zwZC~_jm5|~d!6t7SorB@WJ-I|)hA<$26N6-Y|Cb;@PD&J2r3iXIg^(DV-__BSU3Ev zsS?M!gwUQNzvc6~q@vLh2fkJv(*>g_!^TeZ8BvwoAr;i^L9lz-!oUN1DoJm+YpV3#(Z7G;x&onc(J_y4O?iO!HzRIk zixV()Y&?=|3#bvA_Tf%iJrF!6)^h;csM;}~HE-l4k$JAx8lH(SMFE3WCHqji{+r70 zf-4)r@|b@2p5tKFC^lU)?3})sMbRJL*oyjg-Za}0lX4e!_QTCLB7^{UU~l-pd|x%D zQ$&eZ0w;K|zY>3Q|?7*VbqtD~Uz>$&Qq zgc-IaFyk)bVsaWv_FcIAa%_!>Np{`-O-iuewdgvt2Sw*TK3Q0h={cyY4={WLR&tIz zC9BBJIul0zlj7?WxnXL%Q?O#?SLTN_Do~{EA=J9|EBL;cDWhK$SCp4yBANEaWJNT3 z=KKQDky@2g38`mOTj3m=!P`w%KxFA=h@F7IY1}=i0@afNJOq zP;01~Kdv=wL3@(Y!!Bohwwy`x`{A17*R#W&Jb0LzhX2`pLzWFDZlvE7(S-m5de&2Y z;IGe0N8E5ifXIz@k^laO9fYaDp`jLP=EGpLv)6UIgjth)Z?vM1|Ll|?1usU9L!##= zp1J_J+WX1$?}mkB*za<7y5eKos}Z{5P41avWw?n|uPdRM$;)|^F(u$oLM{?Ij~!rO z*I_;D`S@d#Ppi+#j{^OervUBA1h~Y_$FNDAz>0%mwv%N!d#j0}zY*twx}AZ3YJNCi ziNt-v++pj9d=<+X*%F_&8HrdV{~ZVI*(yulsS5CMSaf zIi#VNj$gF7h{Z4VT=RiKIjoXWBomih@10?h{)NGl-n=?byG~f_71#K74=n9&tj(&2 zA#XzCt)JY{+lIcWk@`e)0OaZdULU3_LK6A4moE`D;jen*#e-3_kg$GE!5EEHr5f+o zjHVh=(Ddlsa{)3|gT9#Xtyq%qCOyPs1&c1m6|kpRSJT{d``q4=_(&?H0@*>GbtWHUPe^k!o}06s9?DUl<|7!GU(j6JkuA3 zJxgbZ*W4J(d%U*%%e9|t4#por5C1zDV65X3N`YW9Bb?(Wa0SavxN7l{IM2qN+w>$>$^|^#STrEY$DXguve>i-4ER;y$Pvl zy@&@K8a$1C^=&<)iMP;AyT9ue)dR$MdEXUuR2IQ&pi$CAiJ}MqdxG~mJ~SMPFDF9| zdYT<@H%Vil+#}UNtOXw#2(2P^u{5YXk2wFJ(=jva&F`B)5U4{X2WzJU{8H(X64zIS zW+f88tb4NZr*I(Nl4+rE64n|{q8^9!i@O5=ajs5gLpl+9A8SvaKJmRpknY&C2=zMi zSq#|d>6L}YzR6EjFL7N*7 zeTMR}9z|A-x!-gY))Nf9^r*cvSme{q@|s7Mn@3Z^6fp%B87eV4Xo)`+L%Nl{@k!$3lljUR9{~t zI0g=SE1hIPdQLKz8TZeKn7ZZfkmlsI>SuDXFGfq3N}FZ7(P0|~6)7iGp?k^NiAr0a z+K1Mqi4uWJ@VRy;I~B=GvUGmjTWLI0z(0$KsT^W~HwT^H1Spx=v{tF~DrojRW-UZj zv?eJEafy=f(%7cbJ$20?nq=wGGO`b+d9S$b&KPYP&GW?RXCT6|dm=bcmreas-%E@tW}6gxGRolSM-$FoQ4iZcYRS<( zqq_~IaPAmM8Y2DCxE)L>sEX~G$KMcO*JWMp*04=d6-oJ&0@eTF6RnM&I)7~}wyL~5 z0yfX9qjeP6H|K;dQ9nM!aEET^;S_P<#yBNusaPF1r}p9l3_eknH~C{J1{TA(iv&Q! z8@T?bycjeiOsqLbO4Ci@H)&;dON5bc#hCVPDtL34bUh96x1oOTf1N@`#5bePDMq0P z5C_(}Lg?kwPM3y}D{){rlriFw>~%uMV=Qf;EI1WTzPgin2PSicGxR;~m|&N#3GwGu zNO#;@sT$nSY7VcxHSrtZl7sozF%fpTWZFq36SyuihQlzzjy43ABnl?XH z!tlx1WL^g?Z|GYtoEYXb2xI%QyBR!e3eJsDg!h+08X~V(E!^t(Kf32x(w^3`OSrl4 zIn3Iz-mmq)@vs{A^Gp!XE0@PS7G}2x7Ij!s;XqnAY;2DiAkFuMe=+Y_JORsiI~2yK z*V(WKJK;Ylxc$zL`BR)yrJD6G*0y-1$M$t&+}JEUsc(0F#y0#KPcUlTA?XjCt?-8M zSUNl6ta*&z`@1S8dWDjB=B1ENw12AJz?w@^u3C*3jbBKrH8z`RjGyb?&as+EL7y&mG6H=7I ziv$;feND^CidH<1IMCA}k)mFC!vS;L$N4M_3p~~EY=*gyh+*d>l%^Ob>hen~LPxDs z37i|>G~Qqt;I#Oxc-Jp~mhlCut}5FZjn`J>ZF6or+Zjh9glJ2gdr3VR- zPNk*0VdySFx}+P)@4nwZ0A?=d?tPxMp73ymUC?E~+w*}$=d~r>XxX_|4TI_CPKzWN zV;G~WUzO&Q-2w`cGjN%%1fmeTWtPMR#?lcr zop(kQzmaz(ziX2>?_&&N&^sUy08%-=S6m!&ph3ty?Y*sk(Q~_*L_DQY|s#%st!Ut6cH>vifa;) zT~xp4k|TU^R+b4jS<_6q$77a=0lP0{x{)Fk^am__!8+xWjyM&Lqm$S3UZ->6kd))a z&inoEx!CC|Saufe0Pjs?{!5%Od!UlKk$Fy|8>@G5rBbNU8HFvYl8-Gls}I2#{eyIq zFH64V%_#k1h_4qnY1b{>7N!dTcZ~mys~3S5Q;jIg#q)RE;L)f$;j4jM}MRl zpboAZ9sKDz871&k`}V4ID<3?0;8Qf~v3F_cVM*8r_-SBN{Y`b?V!{ zk(>RaL*X6v5{)OW3?G;vkMw6{mr$Bl)h*)h=>Mb+h9#dvY!Mly<#<`n#5Sa2(S-e# zbEooe+fl$z44y=(h6d>G(Bm*!MV$m%YeesXIFLc%CZaaY;;Rc-y`ILm>Df8%>L<^ekhk$*59@rR55 zSv`m$P0D0e?R#?QmTNATU*?dVlNAwwBX`m^hLo5PZ`gv-P|JLrF5a(s?1%gaED-Xn zwxG$kBhMm_xUYD(?@p=+iLl!G=%}4Ozp1*(wc92{MBFyr=|{NclJzCGXgT$%MgAF` z%jXi=HDTy*Pyu`mQea8cJwpv9%xRL2r;HvjD1O}%@fW6A&f3>VcE7~M6|NTkT!JEI zh89Q;*@9N5Ic^)eb%~-|QC<^yqA%@w9_J1+yDPcKJILPC&f-`W=fl#wyF&<<&W zKbMAj`%`&&(7ixO-Bem;v@sl5yk{p&5tvV7O;n5q#{>dHy~+;|P>FtnU0-MR^!+u7 zFdG0-o9PHer&A`0b`b=^_I&;vkfrpI8HW#!eyDUf5gART!k0$LT)>s;PsHR{#BKJ7 z-vxg@{icT|)q+7O&zM8sdAGcORc)bLJnC-VzrIL zKAwdxD7D&SYJ)|T{YH;0P1~bRWt)~S@;Jeo6uER%_zyzW6Ex=#iZC-eAbTQp2h2cD z@6m&sw|co~sQh+QCUq$u`snD3B?Gm$I3Em3PR6lcI&f z4erY1gSg17X9v(>cT3PorP=NN#3@^3Vm2r%viIx|@GOr0A*@Ec$Y$3^9qs~_(Wk6c zf4$207l1ibt|y35XdhJ>UYo!*?_MiBlfB21ng>Mo2Gd2FOOZ@oFn7zDG0icw#p2;u zi%=$x?~hNkFjyH#qqo+|7>BlX-jf0M{ps90q%4(0%&0j3hjKwsSh(^DtHc``56ikH)olDmy!{ps z<;T3+s?R8|CB5m-S@s$d6?ds`!cu|RAmby-5*z%WFC>vwLKnHc+WOR6Rxm(Mup>;B z<$HVRAw%HzqXs%&Sbpu>{p;HZ1hVGJ+N|WKip%4$rM&{LvnPr{O=Tgz`M$x9?QV?v zIQ`3j;s*Q=t52Z6bGv9N<(hFEBpN8DdIeru1fu&V5*)v5oSGF2lF;ek01m6?TBWcKZOau_hCp7ow z@cxSF&S3(U)yxH-q?a;9nB}V@Z0#%@$-vWo-Wc6kBo{)Hm-$95D?<;wYun5nL$4Zt z+f}*1Dy0!0#^tdkDwX#Bku!gW{{U;fRpW_>9Qt{7paU}rg`Ri+0|ZGqiqHSPw?8AF z8oQ};FADT`pjjFpJ{KNOixFJbaZ$BdR?Ds#h_XEUAY9CqD2hS{ za8C*+?fgaiIuRo)Nyi#CLTr$xgRG6ZSIA{Ra-*Xt?gN9#w{P3IknSy2q~Sdgj<+F> z@&T_M9qQ<<1L<;_^a9ToAMMOPVx`fO&`C@@ zT*R@C(2hY~SBdBzn^u))B*a4BjZxg>k`q=`U)oH!e991Sc5w>2HpI9cQ7nCReN%7| z5P^GNxrm6px*YUs!NzF^&jadX-I6B(mdJhKOOz|I1U)FCpn`F~!5?9@qw@E&2X3z1 zSz2&I+u&Y1C$tC3pY3BPgPeVCCxVjP$>59FP)kK)pJNAC6MY>zr#fs^b#RC%n>ZfpK?T?dTt&MGr_s1cv)6;55H*bI zD#aAqC&Ln{2q9e@LWwP`K?h~nVnhe`v^n296dpKCi>Xn{LQ#+;KKnhzV5sFj@2Ujx zjQagBo~NMNhLfL#-3)mXNL0A#+wxG~fXg>JvV-?_sUE{pYL*3hX&%U0!pYPGd(^or zPrAW7IWhB6`RMq=ex!Czl#JL|uuXs?BuL}dw2&Ny-WAsl9kLsCC6Z$Jz*HQTT3 z>8OyUXx)jMP=EwBrh@wgAJ#K>wg{zO4X*{&^D}@$>%)KVN^!0G;|fTk8M%#-y^tAT zuNFk3_eER{G;j}+*cb9ZD-_Tw4}$BuZOT`v>w8?>z6bjU6!*qKUu0l$8^aM*Jke-q z>6TU53z1~?a1C>wsxEL2doqh(Ek($e@R8$^tga-Uep%8PSoiB!Xb5NTnFi zBhL@;?yYM1PIr2p<>H26qA?8y6Y<3g$3mfSl3-*)o|qB*P8Op592PbX**~qdH7tnt zhHWG1IrIjVIT9n&rxyJ#zd+%vK*BN?i7j4AAN)1?Ov6k3doTR}wuOaYktV!O*fIWQ zT@FV1MCICDI||}qxDf^jtckR*(i3Q2E0U_7tEe5{w1C$3tIAiEa-8t36=$}w14otj z?Z8AZAsD1MiM-m}?V1!~{(A>|`<45mL=yWzyhZJ+x{vvtfr$7g+;A|@PHq_FLgs=f zjEQg35dxb>NB{1HYR}$J)+EUh$-KTGP?Hj@i=&wcePbq=y|6*@XX}n^;D|-@oUI`wQIG} zSwJ7HQv>$H7}~gDRgYRq4lCUWrWdFMriu1KNj5nnZPg9*dGG=u6It|9TG((giLP93 zQrKl}$eBu+CTj}%R@KP!H$G!WZttQ9LEdLXH5^IE7Q9>DFBn3KD@zYV`3PNBabR0@ zOR^enJk^2=Qal7Xz{*B(E`~3*WIa68jDQ^R)cH*@q8e!mz4IYG(w#J(8`?qCxU@(qdJt0TOtfI-0cn$n|J7G-%+sWxwbRy=`Uy^#v zLatSj6k%w#`TJ0~G3+J=_?fc4c{v;m{0%#@VEaOFYQbQU&g90SjYIQHlTWBpUr2AR z9h_Z^`z(pEZ-P*3X+ma!amHp3=)o2*B}y-msctjEOawu}Kj(Tb=< zs#0b|%emUpI#OY?$_r82Wr`RvENzawOZKbk z#>@*wy-y&yea`q8?OJPjd_-~LeZ>7_20`3gsR}Mz%^YU#ab^fgzg$M(@U57|b+rXCPqF9ah~YN zKHgd<%v0wJfY)-@{q57dFhaTZMR^1#*VuvH?iy=15++M163JTR8{iJ6;3 z^N%9ggoTo9Z|3053{2%q<)U{HtBO~nZ^^l7UK3D&UHXElbm9HEN0Ov_&n<`LeOsqY zenXSfY^K`6oz-=8tnVn7ptqMx(@{ZD*a&8rONa7FF{1^CCW~yN9NGlGfR8sq3KN|& zM!2eSRLGm5c7C1cfEG(-wAF%&ccr$u&IcKT7?dmM^3mXD@G=A;Epg#%EE`@wuhtid zUTeMs>Zi>ww@Wj%>F~R7voX3~6A368_WkdKeYzv?>9+-iL6(KWrF?YhhcYQwrrkQ3 z*L@igeZt?L#^b(R^=}~$>_2nun8b-FWB2Zg7sX6WSsd-4v}CbR!wNCJj=+wlPbo<> z|KVJ7d|+8CQ#^>eg6-`YljKVH7S?JL?qosxfln-*q-4GSW#+g5<3gf*@`d8M)1cSknRSirSzoGd`?}VC?;)Z) zd%y-4Z?cJraJNd)P|(Lr4Dv1;AziVMc7k$e-a5kt zM~Nnn%v02-&!~pFezVr!fjr8aUl^RCZAJxeCfQGdn^677J?CEY)J^94p9|MU8J3l? z8$D`Gg}6lX4lK|rXU1AayKt@FPVj~djLTlLtle5{4pggHZBO+2SY%0fsj3F~E&5yM z2)~w;g|=zeZB2*CqZk5|Qan@4?+D{aIOuCN@6T+dPD8YUzUX=o7q)5mDeVJXij3bZ zkd*ibXm8H-uD4%RV$6F>Jwp_x=p^PtQr8q|RaCLS4iXySlqnOd0BL5BrHuzoTnAoy zF<9mV8;J4KdCoW@XHXRAJ?~_{9!VX(jBCiZaoJm#jJBH>z%| z>c+*##~&ANm}O?N7!!$zZdhTZWW$VQSj#RCL0pn8OKxDw@2MUG6sOqK@5|7?m@juj z++AzJ4t^ex%WPA}g4@c@kHv4(q1XRPsG~D-wyF1wvqiG&KMU35^IwbWbpcTOBS9i# z5w%Xe8upWbS~kt&MPQ@Z)YfxXTv{;N%2`_U*1uA5tJ8OC5uUgm zB~O8Y<%g>dQGdOq;rB>zuKO6avR2i!_)q%4NYfIjL61?a)wc(Q@(BBRM}1G$A1cXc z$+v%}K!B?6z--AuLM3J!=jA1Bn_eL@Koht~zlWZb5SGhxivK^@eE1~RcvW5aSNK*g zUpdWK+Qv(eO7`a)H4$g0i)}POxD*%^YYh&dlH&m@O+Kfe&9h8i;qd-D#$G+hWSM04Hv^+Od=1-QT{l}F8^1z|Ez_DPu(B;M7|uC;KQ_v@DR+61e%l&ZfyW` zo^na6uHM0h$-Q{`z6OaljC0EtQq2$=194>ojfXN?p9(xRp7AFmR)a2qa(BxZV zAV!3G=5^doCbS5AOAZ@le#jVIrI%AuX--b{_sGHuz}bd{4T(_)Dl@PwA=KtpE`Rl% z4@=P;kL@CYUXmbscrMuAUIkOH?m44QG zQ1E3OI_@!n+26tIW2eK%QWy%7?-C8n zH3{psoYXp_m>Nio@bCxVom`p4K(1FQ>mgOAak1d&t)@GGuJvfpdicQfCv}%PuE-89 zL@A7-3dwlpG22{=X>*?7gYTz_DT%ieg87u7vEnNSc}?HU&$_q+%r`PAM4G@m6ys`q zHZgxA>j7fntiqta);Qdz5Wi6Bs2xIEe;mTB@e4XW=_!m7PmxFlV*uG^=VVcWPWgcV z+QU`0wGd5=j{!H1bLuf}ik<`785g~$*K_1oC4rrf#E-EJZdeVq)?RdMU&k$R?+j=F z&0gn+d%9m|YU))DL0*YoUTN*hl|l7~OQ`!UYH!%;S*-n(qA_QM-V%;gH~214@j z6{YXweyJ`6MJ|xQDrwSuRF?Qy-awKyt6R48Z{dz8;?6}HuT@e>TQfTAgLK}Wl;Ajg z>bhch@h5atPyG1p+)I*A=P@{R$}4W3Q_jg(cgZNIkwP|7Q4N20J606X=i$&$FG=}+ zIIa)hVvq^2zv?Ra0{7if#(;2a18FjqBQ~Kz&yK2GChaHLLMh1TH_@RIDX;w|3NlIB z=WNMbXrIiI16h4=Zg`sNd;;#{q<`}F@{0jk96s@w3*~?0rO62!(VLIlV6G?~GZMi$svr3%CfvzL$l+?3z6kiM+$Zk75{3KDuPe4a?F6Q>C%O>@b0G^xR~cL1QQf-{Y2d zsVXln%%8WceI!jHLbkk{nJO`j=bfnRWkpb2WJ69&xU$SY;KI5=)lBe)d0E9r_H+mM zrAITRxH$ji9Y$+SaNMX-V$zH8zOTGUOrD5!W!;CVi8TjdS~`O$hj)3hg=RQexLtzH zDRKCF$+_i!UaGU(W9q=;#d>TtbIB|xVK^L~WiI0DM7gV9=a(uA=l8HQoQPKmpw6U+Hw8=XZN36;{fgm4F!Mq&9u;BGET=G244<_$ z88^{mB0UUZSnRD}`KvTR=%R#6p&L+9%YZ)>*$+j+fAm=7jTFZ6NFK@69M6lxh3bxB zDEAfwX(7nyfxbA<$@O*X8n`#?T#goA#f-WXRe->yk=2Om0!Z2I4Xi|ravlLFkhG+ zJVcJCGDu4p+nvn;YAQ-uQQV1COKOJqSfDjMBYc*=NuNS44i4GVd#ij1LefquPZh0` zkPJ(p>OC*Z45Kbinx!vcuau^>0Q+Ll3j4#U9_8G|)X_W=p1|y7Ot4mH^ttk3*PJrx zH@n4j1r!EX{>Is6qU;eG4|n1MGnQL^qpXANOnP=!*eBDUehLMniOihqQ>oJM1SNbT z$`_wHE{Dj3J#!jz1QEgXnGYQXE5^K>%Yb7pIe+SWmi8B^gf@Li${`&qSb_;46;b`0 zCcJ`-xnnDe6Q{?>i?VbT4~SChrwZ=1QTPd#JpM)J`e@P2*YPC%#3Pt1 zLu-;&)pg#<)Q&n|cIg-1;@uyqAeBWd9W}(l9UA|p7RA{3E^OX+n(h?aBHj*`Bz^b0 z<~TCm0O@(A0(pya157=x7MY?L7ixlo`Yg$olmv9tsTACtC(9=&h$siQg?yNlMsS6b z0&7t0+%Qnc>O4brAJS~bK1>rx4xJA@k+XYL9VZmDf|R2KQ(W0ohvVG#?7IJQG|W0) z_<6vuP#-|T@+fdND%% zmx1>*z$(kg8tFRr*w(p~U%RC_@Jyo*2ncz!)Xkz2`g^_Sj}=8h6=uQ}F)#X4^7*`1 zR=1o}xx9D9>5!w**d93O>kYb4Z2P5eQ=k-TN{m&qV6v0F#H4Sh|aPv)&@OpqW{g>AskvwJU zcjQGvqEc8w^ZW{JCF7Ql=zY0fLt^D1_t()CA_8WQ@n4t_h5Gkl}DFz>0cN;Ge z+H!=%b|4_sUN^w*HEfI0*?^KdC#HXZUs{RJBJwinGk?pE6olu$1l3E-&9!7%<+D@6 zhye_yX=5K&DyVn?UMyefUt!|6adcni|IPosCx6lN`Z(1y4r%qQF;3II=uTs_w+%?DrKAyiqKYhA zaH$CR?n)Kf?OasCyM6%$Etngq#3+)DhQ8K?pAgg@ducp|hZZMq%-?#Ztt|KgZcbrT zJ>0(e%ULCy52@zt3$MR#-e<)cY3ksYgs*e%b*B}MGKT?6*wd1vD#!^R0~m}O!cG{Ki^V7n+>YqP8)Z|jjzE>OFjltj7yBXXH$SHe!5Rv!KT2VU*8TrCDx-G8c zcZP*xe&8pGMOzT3LURt5=16fc(aeIXnb!xRkIB`Fr0wz=7 zxx%j)VB#VTv{OS*MX~$z!K1YWd4BsOHA~EuQjDd>saVDoau$1kYb(}KNAhEx0 zHj{dYq@&myl`P(AcMwLg2)vtoKX!G)^sRvJi(BlkG!R3OCK##9du|O{?bTn-Oy2iP z1i&m{qwv~x*VZV@nCU~VkJ4@>#WLXY&|b*`an?MZ(ZOV>@jLOM3FrX)K+UJ@%cEUD zWAMv)=&-^8Qg~yU2P*ImRPvsJ)<(`iB{zkcz-y;o9;FdhAWECW88$*2sq$P`wo%kK zY%H5xnyE4ALkJVhi<}5!7sUrDBSUz6N@$8RkHz$dJyGZEmT%^Mvu3(KrP-+Y#-%!g zQ>IWO9JKEv$dNA56qWW%y3(d-K_HjV5%5JrNu+Es@}tNpytxp7>@{J$=mHLI1H+EH zaDc^7+4aDBjY_N`VyrYwAOW{`7~cbG8E(lmL`% z5}YF04a_R~nrIxQZUYt3h!NSz7)|-5>!1+sgJSkk#VrD+wFxm=C?-|R*|i7g$UNHe zT`G$FVTykA1AI(ZGMOyIVIT&_iTz6kVxA5oLF9S$5d{ zI$*UIO>X^WJnSCQOQiklAC(8(Y?@z-6l*09p-nHjyQAkL9f$r~IK<_z^X9;9S_xNG z%oo?!N~6j(YAg`yIc!oDC6fK-JD$sLEC*Ju&L)B>Aag+*()B48Hpv^r-F~x4Y+NFO z2}#9#)YLmkGZbnZr28joe4wzP!uM073j6IkN|CY>aFp(MsvqU z^g4q<_Me~kn)GVJNG$f&QQ~=yLc7VamzDYmKgE%~lc}w}r9rkcx)H5Mk(9gasM6GM;saXMf-}#?~_(fL*IZ~*5J6>v-LcX zm#)du&oFvFGA8fV@?u?(sK8q2Ap$=jwIZ35yL@gW*M9*o^e#~cZO#arAQ?HW=lq~2 z*oI0_hiI@*wjVXd$%SBi!gf<2%yI#V+l|~8?iuT+c#ZJ8L#RHx4_DY!dVbzk-FxcjjP4L_9)c}&RMtk#j{d9%qxIazupl8cL z2tFRkPg{>OfGRc)t&v@-J@@REIaXt-vD)oQb_>``|3Db#SR7d)l0zIw=AXN_RbwE3 z!_a7|9@DQ+V+DDfh%Oe%f+eYY|56~SkCYiz87HYN1ENMa@grhb{-JEQI8M{-AcTWG zIe|v{+guM}&sDT9q*A<=%K|4{v+|30x6ykMlgZNdn*cnUo4CWj+1CEd#Di3j%$SWL$Z84?nxi|ff5PiU6@n=N`u z>#IbP*-PaTXk29y$2V{Z zCzwWQLErn4({)MU_o?VPA>?Zmjv2j@{|t|#b#7}h@rMzK^I@pj5_y|(_@!fb3Pd}- zEU!cEbrHy~3yZ+i)HuSIHRM9uD0qM@f(=6!33?$0LFrTT#V*;-tr0f8Y~56BU|fY< zl`Vv2X{(MFtA?paxe@OOY9ot}3xnYA(Rru<{uh$|+o>WZRklw1ci)enzmf_-KM^!i zNeO=YorU;#As^-U_?9jL)e2uVg&7&qaMI8RLuW(%PQ15&eNqF*rTx$ajMwqSn@Kiw zj}lgUw3gviuy`;5S;Nlrb=T zRPKv1O|E10*k}E4q=eGGETap9tP!{?f;pKz@mbIoCM3O(Utt}fxKc{0!sXE+P<$Tc zr3rz=fh)1JFgPavezBpvK5{^{6aFCrB8;Sxj-pCWAI@Vf0U6r3Yy>p-AzZ$pyD%3$ zU$|sr#r65Y*`7}2>)J4yg`K4X*1p@7bhx+`Wvp!R-y(YGd%k|smR__>chkZ^={ff? zm$Ocn=2D!9%01D)siz$iFsa7_^EfsoKzC=CTALI*KfYTGV+o^vR6)&gsFkP^KyAmn zLbxm9%in4brWw=V!9QREilKV=BHv3_Aga=P1n&%p>-}=x$9TnfU`XjZ1biqc$gYcj zX{dLZF(9!Foa;aX%SU@bchm9#r!I6_`sIl-5%I)oz=q&o@@MU9@N1Z)RcWZa;<)7% z-A%_qAv!`&)ebCA0cqRH88eOy+amk#iGvnhRe~j1nOaxE+{ANKJ}Ex9S9nI)Kr$72 z*{y72mR#J@8h>}T{9jP}8iwl0ssGPawf>o`>&<^@06JG(P` zcCwtj*w2+NB%^YD7zxMq`FM&c1=R*1-7h6DRg5ZA(Ukt>N#;kqDTyl1apEB=cz35m z31s&kIxE}~<$o9s*S@roxN_2yn=!hR-VF{6_)Y|a5dO*;aDSvl(3L3rfPPE98HYhB z+EV}7z6OnWhAc~}lQ~}$kgsq9>dET!kJ#rbGl79DqC{6t9|3yTHnQn2J?r$te^Sk| zY++Π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 Date: Fri, 19 Aug 2016 05:58:59 +0530 Subject: [PATCH 144/314] Update styles --- assets/styles/layout/containers.scss | 2 +- assets/styles/scales/color.scss | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/styles/layout/containers.scss b/assets/styles/layout/containers.scss index cc06dc61..ba0564b2 100644 --- a/assets/styles/layout/containers.scss +++ b/assets/styles/layout/containers.scss @@ -1,5 +1,5 @@ .container { - max-width: 1100px; + max-width: 1300px; width: 90%; margin-right: auto; margin-left: auto; diff --git a/assets/styles/scales/color.scss b/assets/styles/scales/color.scss index 5df06a78..eed3a681 100644 --- a/assets/styles/scales/color.scss +++ b/assets/styles/scales/color.scss @@ -9,12 +9,12 @@ $color-brand: rgb(30, 44, 79); $color-accent: rgb(51, 195, 240); // Theme Light -// $color-foreground: rgb(0, 0, 0); -// $color-background: rgb(255, 255, 255); +$color-foreground: rgb(0, 0, 0); +$color-background: rgb(255, 255, 255); // Theme Dark -$color-foreground: rgb(255, 255, 255); -$color-background: rgb(30, 44, 79); +// $color-foreground: rgb(255, 255, 255); +// $color-background: rgb(30, 44, 79); /* Brand Shades From 9fdbef76d4f19fbdd7eff26bbb18a936f03a49b6 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 19 Aug 2016 06:08:28 +0530 Subject: [PATCH 145/314] Add overview containers --- .../{components => containers}/musters.jsx | 10 ++--- assets/scripts/containers/overview.jsx | 39 +++++++++++++++++++ assets/scripts/containers/performance.jsx | 0 assets/scripts/index.js | 12 +++++- 4 files changed, 54 insertions(+), 7 deletions(-) rename assets/scripts/{components => containers}/musters.jsx (84%) create mode 100644 assets/scripts/containers/overview.jsx create mode 100644 assets/scripts/containers/performance.jsx diff --git a/assets/scripts/components/musters.jsx b/assets/scripts/containers/musters.jsx similarity index 84% rename from assets/scripts/components/musters.jsx rename to assets/scripts/containers/musters.jsx index 798dba27..4b1cd1bc 100644 --- a/assets/scripts/components/musters.jsx +++ b/assets/scripts/containers/musters.jsx @@ -1,13 +1,13 @@ 'use strict'; import React from 'react'; -import Group from './group.jsx'; +import Group from '../components/group.jsx'; const D3= require('d3'); -const Cards = React.createClass({ +const Musters = React.createClass({ - fetchCards: function() { + fetchMusters: function() { var _this = this; D3.json(_this.props.url) @@ -26,7 +26,7 @@ const Cards = React.createClass({ }; }, componentWillMount: function() { - this.fetchCards(); + this.fetchMusters(); }, render: function(){ return ( @@ -41,4 +41,4 @@ const Cards = React.createClass({ } }); -export default Cards; +export default Musters; diff --git a/assets/scripts/containers/overview.jsx b/assets/scripts/containers/overview.jsx new file mode 100644 index 00000000..00f47bb5 --- /dev/null +++ b/assets/scripts/containers/overview.jsx @@ -0,0 +1,39 @@ +'use strict'; + +import React from 'react'; + +const D3= require('d3'); + +const Overview = React.createClass({ + + fetchData: function() { + + var _this = this; + D3.json(_this.props.url) + .on('load', function(json) { + _this.setState({overview: json}); + }) + .on('error', function(error) { + console.error(_this.props.url, status, error.toString()); + }) + .get(); + }, + + getInitialState: function() { + return { + overview: [] + }; + }, + componentWillMount: function() { + this.fetchData(); + }, + render: function(){ + return ( +
    + +
    + ); + } +}); + +export default Overview; diff --git a/assets/scripts/containers/performance.jsx b/assets/scripts/containers/performance.jsx new file mode 100644 index 00000000..e69de29b diff --git a/assets/scripts/index.js b/assets/scripts/index.js index 824fb3ef..3fa2baf5 100644 --- a/assets/scripts/index.js +++ b/assets/scripts/index.js @@ -2,9 +2,17 @@ import React from 'react'; import {render} from 'react-dom'; -import Musters from './components/musters.jsx'; +import Musters from './containers/musters.jsx'; +import Overview from './containers/overview.jsx'; import ActiveLink from './lib/active-link'; ActiveLink.init(); -render( , document.getElementById('musters')); + +if (window.location.pathname === '/musters') { + render( , document.getElementById('musters')); +} + +if (window.location.pathname === '/overview') { + render( , document.getElementById('overview')); +} From 2a7e789e1c218c661995299a779a2540bdf74df1 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 19 Aug 2016 18:12:40 +0530 Subject: [PATCH 146/314] Add overview text --- app/templates/overview/overview.hbs | 18 ++++++++++++++++++ assets/scripts/containers/overview.jsx | 6 +++--- assets/styles/index.scss | 1 + assets/styles/scales/color.scss | 8 ++++---- assets/styles/views/overview.scss | 13 +++++++++++++ 5 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 assets/styles/views/overview.scss diff --git a/app/templates/overview/overview.hbs b/app/templates/overview/overview.hbs index e69de29b..84535b89 100644 --- a/app/templates/overview/overview.hbs +++ b/app/templates/overview/overview.hbs @@ -0,0 +1,18 @@ +
    +
    +
    +
    + Surat Singh +
    +

    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, + quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse + cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non + proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    +
    +
    + +
    +
    +
    diff --git a/assets/scripts/containers/overview.jsx b/assets/scripts/containers/overview.jsx index 00f47bb5..db8040e4 100644 --- a/assets/scripts/containers/overview.jsx +++ b/assets/scripts/containers/overview.jsx @@ -11,7 +11,7 @@ const Overview = React.createClass({ var _this = this; D3.json(_this.props.url) .on('load', function(json) { - _this.setState({overview: json}); + _this.setState({overview: json.overview}); }) .on('error', function(error) { console.error(_this.props.url, status, error.toString()); @@ -29,8 +29,8 @@ const Overview = React.createClass({ }, render: function(){ return ( -
    - +
    +
    ); } diff --git a/assets/styles/index.scss b/assets/styles/index.scss index a6fda965..846a2a06 100644 --- a/assets/styles/index.scss +++ b/assets/styles/index.scss @@ -52,3 +52,4 @@ Bootstrap Styles @import 'views/home'; @import 'views/musters'; +@import 'views/overview'; diff --git a/assets/styles/scales/color.scss b/assets/styles/scales/color.scss index eed3a681..5df06a78 100644 --- a/assets/styles/scales/color.scss +++ b/assets/styles/scales/color.scss @@ -9,12 +9,12 @@ $color-brand: rgb(30, 44, 79); $color-accent: rgb(51, 195, 240); // Theme Light -$color-foreground: rgb(0, 0, 0); -$color-background: rgb(255, 255, 255); +// $color-foreground: rgb(0, 0, 0); +// $color-background: rgb(255, 255, 255); // Theme Dark -// $color-foreground: rgb(255, 255, 255); -// $color-background: rgb(30, 44, 79); +$color-foreground: rgb(255, 255, 255); +$color-background: rgb(30, 44, 79); /* Brand Shades diff --git a/assets/styles/views/overview.scss b/assets/styles/views/overview.scss new file mode 100644 index 00000000..713603a9 --- /dev/null +++ b/assets/styles/views/overview.scss @@ -0,0 +1,13 @@ +.overview{ + padding-top: 80px; +} +.overview-title{ + font-size: 4em; + color: $color-accent +} +.overview-desc{ + padding-top: 40px; + line-height: 1.8em; + color: $color-grey-darker; + letter-spacing: .07em +} From 83a4fa01312a2b7ba359b229f8956e8865cf18ef Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Sun, 21 Aug 2016 09:56:19 +0530 Subject: [PATCH 147/314] Finish up overview screen --- app/templates/overview/overview.hbs | 4 ++-- assets/scripts/components/tile.jsx | 31 ++++++++++++++++++++++++++ assets/scripts/containers/overview.jsx | 11 ++++++--- assets/styles/views/overview.scss | 16 +++++++++++++ 4 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 assets/scripts/components/tile.jsx diff --git a/app/templates/overview/overview.hbs b/app/templates/overview/overview.hbs index 84535b89..02bd0ddd 100644 --- a/app/templates/overview/overview.hbs +++ b/app/templates/overview/overview.hbs @@ -2,7 +2,7 @@
    - Surat Singh + {{credentials.firstname}} {{credentials.lastname}}

    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, @@ -12,7 +12,7 @@ proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    - +
    diff --git a/assets/scripts/components/tile.jsx b/assets/scripts/components/tile.jsx new file mode 100644 index 00000000..1f60c14b --- /dev/null +++ b/assets/scripts/components/tile.jsx @@ -0,0 +1,31 @@ +'use strict'; + +import React from 'react'; + +const Tile = React.createClass({ + + render: function(){ + return ( +
    +
    {this.props.data.region_name}
    +
    +
    +
    CURRENT
    +
    {this.props.data.current_total}
    +
    +
    +
    DELAYED
    +
    {this.props.data.delayed_total}
    +
    +
    +
    DAYS TO PAYMENT
    +
    {this.props.data.days_to_payment}
    +
    +
    +
    + ); + } +}); + + +export default Tile; diff --git a/assets/scripts/containers/overview.jsx b/assets/scripts/containers/overview.jsx index db8040e4..78dbe22b 100644 --- a/assets/scripts/containers/overview.jsx +++ b/assets/scripts/containers/overview.jsx @@ -1,6 +1,7 @@ 'use strict'; import React from 'react'; +import Tile from '../components/tile.jsx'; const D3= require('d3'); @@ -29,9 +30,13 @@ const Overview = React.createClass({ }, render: function(){ return ( -
    - -
    +
    + { + this.state.overview.map(function(data, i) { + return ; + }) + } +
    ); } }); diff --git a/assets/styles/views/overview.scss b/assets/styles/views/overview.scss index 713603a9..8629d980 100644 --- a/assets/styles/views/overview.scss +++ b/assets/styles/views/overview.scss @@ -11,3 +11,19 @@ color: $color-grey-darker; letter-spacing: .07em } +.overview-wrapper{ + padding: 30px 70px; + +} +.overview-card-title{ + display: inline-block; + border-bottom: solid 1px $color-grey-lighter; + padding-bottom: 10px; + font-size: 2.5em; + text-transform: uppercase; + letter-spacing: .2em +} +.overview-card-details{ + font-size: 2em; + padding: 30px 0; +} From d730f4216366488802c37ac2eddbe0acf7a5fb63 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Sun, 21 Aug 2016 14:33:20 +0530 Subject: [PATCH 148/314] Update muster api naming convention --- app/helpers/musters_parser.js | 2 +- assets/scripts/containers/musters.jsx | 2 +- assets/scripts/containers/performance.jsx | 44 +++++++++++++++++++++++ assets/styles/scales/color.scss | 8 ++--- 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/app/helpers/musters_parser.js b/app/helpers/musters_parser.js index 5f977a52..6cf74049 100644 --- a/app/helpers/musters_parser.js +++ b/app/helpers/musters_parser.js @@ -63,7 +63,7 @@ exports.block = function(rows) { }); var data = { - 'cards': cards + 'musters': cards }; return data; diff --git a/assets/scripts/containers/musters.jsx b/assets/scripts/containers/musters.jsx index 4b1cd1bc..d6cdcd7b 100644 --- a/assets/scripts/containers/musters.jsx +++ b/assets/scripts/containers/musters.jsx @@ -12,7 +12,7 @@ const Musters = React.createClass({ var _this = this; D3.json(_this.props.url) .on('load', function(json) { - _this.setState({musters: json.cards}); + _this.setState({musters: json.musters}); }) .on('error', function(error) { console.error(_this.props.url, status, error.toString()); diff --git a/assets/scripts/containers/performance.jsx b/assets/scripts/containers/performance.jsx index e69de29b..347f537c 100644 --- a/assets/scripts/containers/performance.jsx +++ b/assets/scripts/containers/performance.jsx @@ -0,0 +1,44 @@ +'use strict'; + +import React from 'react'; +import Tile from '../components/tile.jsx'; + +const D3= require('d3'); + +const Overview = React.createClass({ + + fetchData: function() { + + var _this = this; + D3.json(_this.props.url) + .on('load', function(json) { + _this.setState({performance: json.performance}); + }) + .on('error', function(error) { + console.error(_this.props.url, status, error.toString()); + }) + .get(); + }, + + getInitialState: function() { + return { + performance: [] + }; + }, + componentWillMount: function() { + this.fetchData(); + }, + render: function(){ + return ( +
    + { + this.state.performance.map(function(data, i) { + return
  • ; + }) + } +
    + ); + } +}); + +export default Overview; diff --git a/assets/styles/scales/color.scss b/assets/styles/scales/color.scss index 5df06a78..eed3a681 100644 --- a/assets/styles/scales/color.scss +++ b/assets/styles/scales/color.scss @@ -9,12 +9,12 @@ $color-brand: rgb(30, 44, 79); $color-accent: rgb(51, 195, 240); // Theme Light -// $color-foreground: rgb(0, 0, 0); -// $color-background: rgb(255, 255, 255); +$color-foreground: rgb(0, 0, 0); +$color-background: rgb(255, 255, 255); // Theme Dark -$color-foreground: rgb(255, 255, 255); -$color-background: rgb(30, 44, 79); +// $color-foreground: rgb(255, 255, 255); +// $color-background: rgb(30, 44, 79); /* Brand Shades From da947c87d208459e588283e1c0604603f0f16bb2 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Mon, 22 Aug 2016 14:04:41 +0530 Subject: [PATCH 149/314] Update performance api structure and selector --- app/controllers/performance/performance.js | 13 +- app/helpers/performance_parser.js | 38 +- app/templates/performance/performance.hbs | 1 + assets/scripts/containers/performance.jsx | 21 +- assets/scripts/index.js | 5 + assets/styles/index.scss | 1 + assets/styles/vendor/select/react-select.scss | 371 ++++++++++++++++++ assets/styles/views/overview.scss | 5 +- package.json | 1 + 9 files changed, 422 insertions(+), 34 deletions(-) create mode 100644 assets/styles/vendor/select/react-select.scss diff --git a/app/controllers/performance/performance.js b/app/controllers/performance/performance.js index b21e59ab..edb49121 100644 --- a/app/controllers/performance/performance.js +++ b/app/controllers/performance/performance.js @@ -22,21 +22,18 @@ exports.getData = { type: sequelize.QueryTypes.SELECT }).then(function(rows) { + var data; if (role === 'block') { - - var data = PerformanceParser.block(rows); - + data = PerformanceParser.block(rows); } else if (role === 'district') { - - var data = PerformanceParser.district(rows); - + data = PerformanceParser.district(rows); } data.config = { role: role, headers: ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'tot_trn'], - labels: Translate('/payment_steps_labels', request.auth.credentials), - y_axis_label : Translate('/y_axis_labels', request.auth.credentials), + labels: Translate('/payment_steps_labels', request.auth.credentials), + y_axis_label: Translate('/y_axis_labels', request.auth.credentials), compare_chart_labels: Translate('/compare_chart_labels', request.auth.credentials), comparison_lines: role === 'block' ? ['block', 'district', 'state'] : ['district', 'state'] }; diff --git a/app/helpers/performance_parser.js b/app/helpers/performance_parser.js index 90f1a760..2b3ec3c0 100644 --- a/app/helpers/performance_parser.js +++ b/app/helpers/performance_parser.js @@ -87,7 +87,7 @@ exports.block = function(rows) { // Process list of panchayat names and codes var panchayatResponse = D3.values(rows[3]); - + // Nest the panchayat response var panchayatPerformance = D3.nest() .key(function(d) { @@ -118,23 +118,25 @@ exports.block = function(rows) { .entries(panchayatResponse) .map(function(d) { return { - 'block_code': d.key.substr(0,7), + 'block_code': d.key.substr(0, 7), 'block_name': d.key.substr(7), - 'data': d.values.map(function(e) { + 'data': d.values.map(function(e) { return e.values; }) }; }); var data = { - 'state_performance': statePerformance, - 'district_performance': districtPerformance, - 'block_performance': blockPerformance, - 'panchayat_performance': panchayatPerformance - } + performance: { + 'state': statePerformance, + 'district': districtPerformance, + 'block': blockPerformance, + 'panchayat': panchayatPerformance + } + }; return data; -} +}; exports.district = function(rows) { @@ -196,7 +198,7 @@ exports.district = function(rows) { // Process list of block names and codes var blockResponse = D3.values(rows[2]); - + // Nest the block response var blockPerformance = D3.nest() .key(function(d) { @@ -227,19 +229,21 @@ exports.district = function(rows) { .entries(blockResponse) .map(function(d) { return { - 'district_code': d.key.substr(0,4), + 'district_code': d.key.substr(0, 4), 'district_name': d.key.substr(4), - 'data': d.values.map(function(e) { + 'data': d.values.map(function(e) { return e.values; }) }; }); var data = { - 'state_performance': statePerformance, - 'district_performance': districtPerformance, - 'block_performance': blockPerformance - } + performance: { + 'state': statePerformance, + 'district': districtPerformance, + 'block': blockPerformance + } + }; return data; -} +}; diff --git a/app/templates/performance/performance.hbs b/app/templates/performance/performance.hbs index e69de29b..4fa965ef 100644 --- a/app/templates/performance/performance.hbs +++ b/app/templates/performance/performance.hbs @@ -0,0 +1 @@ +
    diff --git a/assets/scripts/containers/performance.jsx b/assets/scripts/containers/performance.jsx index 347f537c..3110f090 100644 --- a/assets/scripts/containers/performance.jsx +++ b/assets/scripts/containers/performance.jsx @@ -1,7 +1,7 @@ 'use strict'; import React from 'react'; -import Tile from '../components/tile.jsx'; +import Select from 'react-select'; const D3= require('d3'); @@ -12,7 +12,9 @@ const Overview = React.createClass({ var _this = this; D3.json(_this.props.url) .on('load', function(json) { - _this.setState({performance: json.performance}); + _this.setState({ + config: json.config + }); }) .on('error', function(error) { console.error(_this.props.url, status, error.toString()); @@ -29,13 +31,18 @@ const Overview = React.createClass({ this.fetchData(); }, render: function(){ + var options = [ + { value: 'one', label: 'One' }, + { value: 'two', label: 'Two' } + ]; + + function logChange(val) { + console.log('Selected: ' + val); + } + return (
    - { - this.state.performance.map(function(data, i) { - return
  • ; - }) - } + + + onChange={this.setValue} + value={this.state.value} + valueRenderer={this.renderValue} />
    ); } From dcdeb547656bcc010ba73cd982ca871bc03c6050 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Tue, 23 Aug 2016 16:51:43 +0530 Subject: [PATCH 156/314] Implement loading sign on selector --- assets/scripts/containers/performance.jsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/assets/scripts/containers/performance.jsx b/assets/scripts/containers/performance.jsx index 8d6cbd64..fa8e10e0 100644 --- a/assets/scripts/containers/performance.jsx +++ b/assets/scripts/containers/performance.jsx @@ -15,7 +15,8 @@ const Overview = React.createClass({ .on('load', function(json) { _this.setState({ config: json.config, - performance: json.performance + performance: json.performance, + isLoadingExternally : false, }); }) .on('error', function(error) { @@ -26,7 +27,8 @@ const Overview = React.createClass({ getInitialState: function() { return { performance: {}, - config: {} + config: {}, + isLoadingExternally : true, }; }, componentWillMount: function() { @@ -45,7 +47,6 @@ const Overview = React.createClass({ render: function(){ var list = Regions.list(this.state.performance, this.state.config); - return (
    +
    + + ); + } +}); + + +export default Subnav; diff --git a/assets/scripts/containers/performance.jsx b/assets/scripts/containers/performance.jsx index fa8e10e0..0f3dd354 100644 --- a/assets/scripts/containers/performance.jsx +++ b/assets/scripts/containers/performance.jsx @@ -1,11 +1,9 @@ 'use strict'; import React from 'react'; -import Select from 'react-select'; - +import Subnav from '../components/subnav.jsx'; const D3= require('d3'); -const Regions = require('../lib/region'); const Overview = React.createClass({ @@ -16,7 +14,7 @@ const Overview = React.createClass({ _this.setState({ config: json.config, performance: json.performance, - isLoadingExternally : false, + isFetching : false, }); }) .on('error', function(error) { @@ -28,36 +26,17 @@ const Overview = React.createClass({ return { performance: {}, config: {}, - isLoadingExternally : true, + isFetching : true, }; }, componentWillMount: function() { this.fetchData(); }, - renderOption: function(option) { - return {option.label}; - }, - renderValue: function(option) { - return {option.label}; - }, - setValue (value) { - this.setState({ value }); - console.log('Support level selected:', value.label); - }, render: function(){ - var list = Regions.list(this.state.performance, this.state.config); return (
    - + + + + + + + + +
    +
    +
    Total transactions on
    +
    +
    +
    +
    +
    + ); + } +}); + + +export default ComparisonChart; + + + + + + + diff --git a/assets/scripts/containers/performance.jsx b/assets/scripts/containers/performance.jsx index aa4d4d4b..3cf89520 100644 --- a/assets/scripts/containers/performance.jsx +++ b/assets/scripts/containers/performance.jsx @@ -3,6 +3,7 @@ import React from 'react'; import Subnav from '../components/subnav.jsx'; import PerformanceChart from '../components/performance-chart.jsx'; +import ComparisonChart from '../components/comparison-chart.jsx'; const D3= require('d3'); @@ -45,6 +46,8 @@ const Overview = React.createClass({
    +
    +
    ); } diff --git a/assets/styles/helpers/utils.scss b/assets/styles/helpers/utils.scss index 787d9fa2..fe8c7587 100644 --- a/assets/styles/helpers/utils.scss +++ b/assets/styles/helpers/utils.scss @@ -22,6 +22,10 @@ .u-spacing-page-top { padding-top: 6rem; } +.u-region-divider { + margin: 50px 0 30px; + border-bottom: dashed 1px $color-grey-lighter; +} // // Self Clearing Goodness // From 6c2cf10a01478e770a3fb915173b7291a7ccad4c Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 25 Aug 2016 14:27:57 +0530 Subject: [PATCH 188/314] Add benchmarking components --- assets/scripts/components/comparison-chart.jsx | 6 +++++- assets/styles/views/performance.scss | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/assets/scripts/components/comparison-chart.jsx b/assets/scripts/components/comparison-chart.jsx index 7c35852a..1d287bf4 100644 --- a/assets/scripts/components/comparison-chart.jsx +++ b/assets/scripts/components/comparison-chart.jsx @@ -54,7 +54,11 @@ const ComparisonChart = React.createClass({ -
    +
    +
    +
    +
    +
    Total transactions on
    diff --git a/assets/styles/views/performance.scss b/assets/styles/views/performance.scss index 2b0d8869..aa47f1fa 100644 --- a/assets/styles/views/performance.scss +++ b/assets/styles/views/performance.scss @@ -33,3 +33,20 @@ width: 33%; display: inline-block; } +.group-selector { + padding: 14px 10px 10px; + border-radius: 3px; + border: solid 1px $color-grey-lightest; +} + +.group-selector label input[type="checkbox"] { + margin-top: -3px; + margin-right: 6px; +} +.button--pc, +.button--pc:hover, +.button--pc:focus { + font-size: 1rem; + text-transform: none; + width: 100%; +} From 9d6102bc1b84c61b3430d66a8af876a8e03c8bcd Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 25 Aug 2016 16:53:47 +0530 Subject: [PATCH 189/314] Add benchmarking chart --- .../scripts/components/comparison-chart.jsx | 134 +++++++++++++----- assets/scripts/components/subnav.jsx | 1 - 2 files changed, 101 insertions(+), 34 deletions(-) diff --git a/assets/scripts/components/comparison-chart.jsx b/assets/scripts/components/comparison-chart.jsx index 1d287bf4..6f198040 100644 --- a/assets/scripts/components/comparison-chart.jsx +++ b/assets/scripts/components/comparison-chart.jsx @@ -10,26 +10,94 @@ const ComparisonChart = React.createClass({ loadChart: function(){ - // var data; - // var _this = this; - - // if(_this.props.activeRegion && _this.props.activeRegion.region_type === 'block'){ - // data = _this.props.performance[_this.props.activeRegion.region_type][_this.props.activeRegion.block_index].data; - // } - // else if(_this.props.activeRegion && _this.props.activeRegion.region_type === 'panchayat'){ - // data = _this.props.performance[_this.props.activeRegion.region_type][_this.props.activeRegion.block_index].data[_this.props.activeRegion.panchayat_index].data; - // }else { - // return; - // } - - // var parsed_data = Parser.lines({ - // data: data, - // col: [1, 2, 3, 4, 5, 6, 7], - // isCumulative: true - // }); + var _this = this; + var c_data = []; + var legend_target = '.comparison_legend'; + + if(!_this.props.activeRegion) { + return; + } + var comparison_lines = ['state', 'district']; + + comparison_lines.forEach(function(comparison_line, index) { + var line_data = Parser.lines({ + data: _this.props.performance[comparison_line].data, + col: [1,2,3,4,5,6,7], + isCumulative: false + }); + if (line_data[0]) { + c_data.push(line_data[0]); // Workaround to append region data + } + }); + + MG.data_graphic({ + // title: options.title, + title: '', + target: _this.elem, + data: c_data, + width: 600, + height: 500, + left: 100, + full_width: true, + decimals: 0, + xax_count: 10, + // max_x : options.max_x || null, + // min_x: options.min_x || null, + xax_format: D3.time.format('%b, %y'), + chart_type: c_data.length !== 0 ? 'line' : 'missing-data', + missing_text: 'No data', + show_secondary_x_label: false, + x_extended_ticks: true, + legend: _this.props.config.labels, + legend_target: '.comparison_legend', + show_tooltips: false, + aggregate_rollover: true, + show_year_markers: true, + point_size : 3.5, + transition_on_update: true, + interplate: 'linear', + interpolate_tension: 1, + area: false, + y_label: _this.props.config.y_axis_label, + show_rollover_text: false, + mouseover: function(d, i) { + if (!d.values) { + d.values = [d]; + } + if (c_data.length) { + for (i = 1; i <= c_data.length; i++) { + var l_span = D3.select(legend_target + ' .mg-line' + i + '-legend-color'); + l_span.text(' '); + l_span.text('— ' +_this.props.config.labels[i - 1]); + } + } + d.values.forEach(function(val, index) { + var prefix = D3.formatPrefix(val.value); + var l_span = D3.select(legend_target + ' .mg-line' + val.line_id + '-legend-color'); + l_span.text(' '); + l_span.text('— ' +_this.props.config.labels[val.line_id - 1] + ' : ' + prefix.scale(val.value).toFixed(0)); + var format = D3.time.format('%b, %Y'); + D3.select('#region_comparison_total_trans').text(format(val.date) + ': ' + val.total_trans); + }); + }, + mouseout: function(d, i) { + if (!d.values) { + d.values = [d]; + } + D3.select('#region_comparison_total_trans').text(''); + d.values.forEach(function(val, index) { + var l_span = D3.select(legend_target + ' .mg-line' + val.line_id + '-legend-color'); + l_span.text(' '); + l_span.text('— ' +_this.props.config.labels[val.line_id - 1]); + }); + } + }); }, + stepChange: function(event){ + console.log(event.target.value); + }, componentDidMount: function() { this.loadChart(); }, @@ -39,33 +107,33 @@ const ComparisonChart = React.createClass({ render: function(){ return (
    -
    +

    Benchmarking Your Performance

    Compare your performance with averages for your district and state.

    - + + + + + + +
    -
    -
    -
    +
    +
    +
    Total transactions on
    -
    -
    -
    -
    +
    +
    {if (el){this.elem = el;}}}>
    +
    +
    ); } }); diff --git a/assets/scripts/components/subnav.jsx b/assets/scripts/components/subnav.jsx index b19599a1..10a5d351 100644 --- a/assets/scripts/components/subnav.jsx +++ b/assets/scripts/components/subnav.jsx @@ -20,7 +20,6 @@ const Subnav = React.createClass({ }, setValue (value) { this.setState({ value }); - console.log('Support level selected:', value.label); this.props.onRegionChange(value); // Load graph logic here }, From 1ada7993ee0ac3e368ef95a418c2cd5898d70486 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 25 Aug 2016 18:36:04 +0530 Subject: [PATCH 190/314] Add data and legend to performance comaprison chart --- .../scripts/components/comparison-chart.jsx | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/assets/scripts/components/comparison-chart.jsx b/assets/scripts/components/comparison-chart.jsx index 6f198040..250f6c5b 100644 --- a/assets/scripts/components/comparison-chart.jsx +++ b/assets/scripts/components/comparison-chart.jsx @@ -8,6 +8,14 @@ const Parser = require('../lib/parser'); const ComparisonChart = React.createClass({ + + // comparisonLabels : function(internals) { + // var labels = []; + // internals.active_compare_lines.forEach(function(comparison_line, index) { + // labels.push(internals.data.monthwise[comparison_line][comparison_line + '_name'] + ' ' + internals.data.config.compare_chart_labels[comparison_line]); + // }); + // return labels; + // }, loadChart: function(){ var _this = this; @@ -19,11 +27,23 @@ const ComparisonChart = React.createClass({ } var comparison_lines = ['state', 'district']; + comparison_lines.push(_this.props.activeRegion.region_type); comparison_lines.forEach(function(comparison_line, index) { + + var data; + if(_this.props.activeRegion.region_type === 'block' && comparison_line ==='block'){ + data = _this.props.performance[_this.props.activeRegion.region_type][_this.props.activeRegion.block_index].data; + } + else if(_this.props.activeRegion.region_type === 'panchayat' && comparison_line ==='panchayat'){ + data = _this.props.performance[_this.props.activeRegion.region_type][_this.props.activeRegion.block_index].data[_this.props.activeRegion.panchayat_index].data; + }else { + data = _this.props.performance[comparison_line].data; + } + var line_data = Parser.lines({ - data: _this.props.performance[comparison_line].data, - col: [1,2,3,4,5,6,7], + data: data, + col: [1], isCumulative: false }); if (line_data[0]) { @@ -49,7 +69,7 @@ const ComparisonChart = React.createClass({ missing_text: 'No data', show_secondary_x_label: false, x_extended_ticks: true, - legend: _this.props.config.labels, + legend: comparison_lines, legend_target: '.comparison_legend', show_tooltips: false, aggregate_rollover: true, @@ -69,14 +89,14 @@ const ComparisonChart = React.createClass({ for (i = 1; i <= c_data.length; i++) { var l_span = D3.select(legend_target + ' .mg-line' + i + '-legend-color'); l_span.text(' '); - l_span.text('— ' +_this.props.config.labels[i - 1]); + l_span.text('— ' + comparison_lines[i - 1]); } } d.values.forEach(function(val, index) { var prefix = D3.formatPrefix(val.value); var l_span = D3.select(legend_target + ' .mg-line' + val.line_id + '-legend-color'); l_span.text(' '); - l_span.text('— ' +_this.props.config.labels[val.line_id - 1] + ' : ' + prefix.scale(val.value).toFixed(0)); + l_span.text('— ' + comparison_lines[val.line_id - 1] + ' : ' + prefix.scale(val.value).toFixed(0)); var format = D3.time.format('%b, %Y'); D3.select('#region_comparison_total_trans').text(format(val.date) + ': ' + val.total_trans); }); @@ -89,7 +109,7 @@ const ComparisonChart = React.createClass({ d.values.forEach(function(val, index) { var l_span = D3.select(legend_target + ' .mg-line' + val.line_id + '-legend-color'); l_span.text(' '); - l_span.text('— ' +_this.props.config.labels[val.line_id - 1]); + l_span.text('— ' + comparison_lines[val.line_id - 1]); }); } }); From 35df0f2a7b5fd12c39fcb1ac3689545dfe2586e9 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Thu, 25 Aug 2016 18:56:40 +0530 Subject: [PATCH 191/314] Make labels dynamic --- app/controllers/performance/performance.js | 2 +- app/locales/en_US/v1.js | 3 ++- .../scripts/components/comparison-chart.jsx | 22 ++++++++++--------- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/app/controllers/performance/performance.js b/app/controllers/performance/performance.js index edb49121..aca1d75b 100644 --- a/app/controllers/performance/performance.js +++ b/app/controllers/performance/performance.js @@ -35,7 +35,7 @@ exports.getData = { labels: Translate('/payment_steps_labels', request.auth.credentials), y_axis_label: Translate('/y_axis_labels', request.auth.credentials), compare_chart_labels: Translate('/compare_chart_labels', request.auth.credentials), - comparison_lines: role === 'block' ? ['block', 'district', 'state'] : ['district', 'state'] + comparison_lines: role === 'block' ? ['district', 'state'] : ['state'] }; reply(data); diff --git a/app/locales/en_US/v1.js b/app/locales/en_US/v1.js index 9bd2d20b..caeac190 100644 --- a/app/locales/en_US/v1.js +++ b/app/locales/en_US/v1.js @@ -86,7 +86,8 @@ module.exports = { compare_chart_labels: { 'state': 'state average', 'district': 'district average', - 'block': 'block average' + 'block': 'block average', + 'panchayat': 'panchayat average' }, y_axis_labels: 'Days to complete process', total_trans: "Total transactions on", diff --git a/assets/scripts/components/comparison-chart.jsx b/assets/scripts/components/comparison-chart.jsx index 250f6c5b..2511319d 100644 --- a/assets/scripts/components/comparison-chart.jsx +++ b/assets/scripts/components/comparison-chart.jsx @@ -21,28 +21,30 @@ const ComparisonChart = React.createClass({ var _this = this; var c_data = []; var legend_target = '.comparison_legend'; + var labels = []; if(!_this.props.activeRegion) { return; } - var comparison_lines = ['state', 'district']; + var comparison_lines = _this.props.config.comparison_lines; comparison_lines.push(_this.props.activeRegion.region_type); comparison_lines.forEach(function(comparison_line, index) { - var data; + var region; if(_this.props.activeRegion.region_type === 'block' && comparison_line ==='block'){ - data = _this.props.performance[_this.props.activeRegion.region_type][_this.props.activeRegion.block_index].data; + region = _this.props.performance[_this.props.activeRegion.region_type][_this.props.activeRegion.block_index]; } else if(_this.props.activeRegion.region_type === 'panchayat' && comparison_line ==='panchayat'){ - data = _this.props.performance[_this.props.activeRegion.region_type][_this.props.activeRegion.block_index].data[_this.props.activeRegion.panchayat_index].data; + region = _this.props.performance[_this.props.activeRegion.region_type][_this.props.activeRegion.block_index].data[_this.props.activeRegion.panchayat_index]; }else { - data = _this.props.performance[comparison_line].data; + region = _this.props.performance[comparison_line]; } + labels.push(region[comparison_line + '_name'] + ' ' + _this.props.config.compare_chart_labels[comparison_line]); var line_data = Parser.lines({ - data: data, + data: region.data, col: [1], isCumulative: false }); @@ -69,7 +71,7 @@ const ComparisonChart = React.createClass({ missing_text: 'No data', show_secondary_x_label: false, x_extended_ticks: true, - legend: comparison_lines, + legend: labels, legend_target: '.comparison_legend', show_tooltips: false, aggregate_rollover: true, @@ -89,14 +91,14 @@ const ComparisonChart = React.createClass({ for (i = 1; i <= c_data.length; i++) { var l_span = D3.select(legend_target + ' .mg-line' + i + '-legend-color'); l_span.text(' '); - l_span.text('— ' + comparison_lines[i - 1]); + l_span.text('— ' + labels[i - 1]); } } d.values.forEach(function(val, index) { var prefix = D3.formatPrefix(val.value); var l_span = D3.select(legend_target + ' .mg-line' + val.line_id + '-legend-color'); l_span.text(' '); - l_span.text('— ' + comparison_lines[val.line_id - 1] + ' : ' + prefix.scale(val.value).toFixed(0)); + l_span.text('— ' + labels[val.line_id - 1] + ' : ' + prefix.scale(val.value).toFixed(0)); var format = D3.time.format('%b, %Y'); D3.select('#region_comparison_total_trans').text(format(val.date) + ': ' + val.total_trans); }); @@ -109,7 +111,7 @@ const ComparisonChart = React.createClass({ d.values.forEach(function(val, index) { var l_span = D3.select(legend_target + ' .mg-line' + val.line_id + '-legend-color'); l_span.text(' '); - l_span.text('— ' + comparison_lines[val.line_id - 1]); + l_span.text('— ' + labels[val.line_id - 1]); }); } }); From 7d4e8b2eea7cf430dba88c1379cd729cdee13ada Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Thu, 25 Aug 2016 13:46:03 -0400 Subject: [PATCH 192/314] Add all paydroid text fields to translations files --- app/locales/en_US/v2.js | 97 +++++++++++++++++++++++++--------- app/locales/hi/v2.js | 113 ++++++++++++++++++++++++++++------------ 2 files changed, 150 insertions(+), 60 deletions(-) diff --git a/app/locales/en_US/v2.js b/app/locales/en_US/v2.js index 881842e7..f67ca8a5 100644 --- a/app/locales/en_US/v2.js +++ b/app/locales/en_US/v2.js @@ -182,7 +182,11 @@ module.exports = { work_code: 'Work code', work_name: 'Work name', closure_date: 'Closure date', - days_delayed: 'Days delayed' + days_delayed: 'Days delayed', + contact: { + phone: 'Phone', + whatsapp: 'WhatsApp' + } }, chart: { days_to_complete_process: 'Days to complete process', @@ -212,30 +216,41 @@ module.exports = { step: 'Step' } }, + user_dropdown: { + profile: 'Profile', + logout: 'Logout' + } profile: { + profile: 'Profile', + edit: 'EDIT', + save:'SAVE', + updating:'UPDATING...' firstname: 'First Name', lastname: 'Last Name', - profile: 'Profile', - account: 'Account', - work_email: 'Work Email', mobile: 'Mobile', personal_email: 'Personal Email', - lang: 'Language', + work_email: 'Work Email', colorblind: 'Use Colorblind-Safe Theme', - settings: 'Settings', - logout: 'Logout', - profile_settings: 'Profile Settings', - email_settings: 'Email Settings', - primary_email_msg: 'Your primary email address will be used for account-related notifications as well as any web-based operations.', - save: 'Update', - your_primary_email: 'Your primary email', + lang: 'Language', + eng: 'English', + hindi: 'Hindi', + change_pass_button: 'CHANGE PASSWORD' + }, + password: { change_pass: 'Change password', old_pass: 'Old password', new_pass: 'New password', pass_confirm: 'Verify new password', - forgot_pass: 'I forgot my password' + forgot_pass: 'I forgot my password', + change_pass_button: 'CHANGE PASSWORD', }, search: 'Search for TA/GRS...', + sort: { + current_total: 'Current total', + delayed_total: 'Delayed total', + name: 'Name', + designation: 'Designation' + }, messages: { login: { connectivity: 'Unable to log in to PayDash. Please try again when your device has internet connectivity.', @@ -255,6 +270,13 @@ module.exports = { password_wrong_old: 'Old password is incorrect. Please contact the PayDash team if you require assistance.', password_new_nomatch: 'New password does not match.', password_tooshort: 'Your new password must be at least 6 characters long.' + password_empty: 'Password cannot be empty', + requesting_change: 'Requesting password change...' + }, + contact: { + contact: 'Contact', + gmail: 'Gmail', + phone: 'Phone' }, whatsapp: { overview:'Muster Roll Details for {name}\n\n{current_total} musters closing today\n{delayed_total} delayed musters\n\n', @@ -282,7 +304,11 @@ module.exports = { t_5: 'Measurement book not filled (T+5)', t_6: 'Wagelist not sent (T+6)', t_7: 'Pending for FTO first signature (T+7)', - t_8: 'Pending for FTO second signature (T+8)' + t_8: 'Pending for FTO second signature (T+8)', + contact: { + phone: 'Phone', + whatsapp: 'WhatsApp' + } }, chart: { days_to_complete_process: 'Days to complete process', @@ -312,30 +338,42 @@ module.exports = { step: 'Step' } }, + user_dropdown: { + profile: 'Profile', + logout: 'Logout' + } profile: { + profile: 'Profile', + edit: 'EDIT', + save:'SAVE', + updating:'UPDATING...' firstname: 'First Name', lastname: 'Last Name', - profile: 'Profile', - account: 'Account', - work_email: 'Work Email', mobile: 'Mobile', personal_email: 'Personal Email', - lang: 'Language', + work_email: 'Work Email', colorblind: 'Use Colorblind-Safe Theme', - settings: 'Settings', - logout: 'Logout', - profile_settings: 'Profile Settings', - email_settings: 'Email Settings', - primary_email_msg: 'Your primary email address will be used for account-related notifications as well as any web-based operations.', - save: 'Update', - your_primary_email: 'Your primary email', + lang: 'Language', + eng: 'English', + hindi: 'Hindi', + change_pass_button: 'CHANGE PASSWORD' + }, + password: { change_pass: 'Change password', old_pass: 'Old password', new_pass: 'New password', pass_confirm: 'Verify new password', - forgot_pass: 'I forgot my password' + forgot_pass: 'I forgot my password', + change_pass_button: 'CHANGE PASSWORD', }, search: 'Search for Block or Officer Name...', + sort: { + current_total: 'Current total', + delayed_total: 'Delayed total', + days_to_payment: 'Avg. days to payment', + block_name: 'Block name', + ceo_name: 'Block CEO name' + }, messages: { login: { connectivity: 'Unable to log in to PayDash. Please try again when your device has internet connectivity.', @@ -355,6 +393,13 @@ module.exports = { password_wrong_old: 'Old password is incorrect. Please contact the PayDash team if you require assistance.', password_new_nomatch: 'New password does not match.', password_tooshort: 'Your new password must be at least 6 characters long.' + password_empty: 'Password cannot be empty', + requesting_change: 'Requesting password change...' + }, + contact: { + contact: 'Contact', + gmail: 'Gmail', + phone: 'Phone' }, whatsapp: 'MGNREGA Payment Delay Performance for {name}\n\n_Block_\n{block_name}\n\n{days_to_payment} days to complete payment\n{current_total} musters closing today\n{delayed_total} delayed musters\n\nMUSTERS DELAYED AT DIFFERENT STEPS\n\n*Attendance not filled (T+2)*\n_Total_\n{t2_total}\n_Avg. days pending_\n{t2_avg}\n\n*Measurement book not filled (T+5)*\n_Total_\n{t5_total}\n_Avg. days pending_\n{t5_avg}\n\n*Wagelist not sent (T+6)*\n_Total_\n{t6_total}\n_Avg. days pending_\n{t6_avg}\n\n*Pending for FTO first signature (T+7)*\n_Total_\n{t7_total}\n_Avg. days pending_\n{t7_avg}\n\n*Pending for FTO second signature (T+8)*\n_Total_\n{t8_total}\n_Avg. days pending_\n{t8_avg}\n' } diff --git a/app/locales/hi/v2.js b/app/locales/hi/v2.js index 8ba6b3fb..6767057c 100644 --- a/app/locales/hi/v2.js +++ b/app/locales/hi/v2.js @@ -186,7 +186,11 @@ module.exports = { work_code: 'कार्य कोड', work_name: 'कार्य नाम', closure_date: 'मस्टर रोल बंद होने की तिथि', - days_delayed: 'विलंब(दिन)' + days_delayed: 'विलंब(दिन)', + contact: { + phone: 'Phone', + whatsapp: 'WhatsApp' + } }, chart: { days_to_complete_process: 'प्रक्रिया पूरी करने में लगे दिन', @@ -216,30 +220,41 @@ module.exports = { step: 'कदम' } }, + user_dropdown: { + profile: 'प्रोफ़ाइल', + logout: 'लौग आउट' + } profile: { + profile: 'प्रोफ़ाइल', + edit: 'EDIT', + save:'SAVE', + updating:'UPDATING...' firstname: 'मूल नाम', lastname: 'उपनाम', - profile: 'प्रोफ़ाइल', - account: 'अकाउंट', - work_email: 'औपचारिक e-mail', mobile: 'मोबाइल नंबर', personal_email: 'निजी e-mail', - lang : 'भाषा', + work_email: 'औपचारिक e-mail', colorblind: 'Use Colorblind-Safe Theme', - settings: 'सेट्टिंग्स', - logout: 'लौग आउट', - profile_settings: 'आपकी प्रोफ़ाइल सेट्टिंग्स', - email_settings: 'E-Mail सेट्टिंग्स', - primary_email_msg: 'आपके अकाउंट से संबंधित संदेशों और इंटरनेट-संबंधित प्रक्रियाओं के लिए आपके मुख्य e-mail ID का उपयोग किया जाएगा|', - save: 'अद्यतन (update)', - your_primary_email: 'आपका मुख्य e-mail ID', + lang: 'भाषा', + eng: 'English', + hindi: 'Hindi', + change_pass_button: 'पासवर्ड बदलें' + }, + password: { change_pass: 'पासवर्ड बदलें', - old_pass: 'पुराना पासवर्ड ', - new_pass: 'नया पासवर्ड ', - pass_confirm:'नये पासवर्ड को सत्यापित करें', - forgot_pass: 'मैं अपना पासवर्ड भूल गयी/गया' + old_pass: 'पुराना पासवर्ड', + new_pass: 'नया पासवर्ड', + pass_confirm: 'नये पासवर्ड को सत्यापित करें', + forgot_pass: 'मैं अपना पासवर्ड भूल गयी/गया', + change_pass_button: 'पासवर्ड बदलें' }, search: 'Search for TA/GRS...', + sort: { + current_total: 'Current total', + delayed_total: 'Delayed total', + name: 'Name', + designation: 'Designation' + }, messages: { login: { connectivity: 'हमे खेद है कि आप log in करने में विफल रहे| कृपया अपने फ़ोन/कंप्यूटर की internet connectivity को जाँच लें|', @@ -258,7 +273,14 @@ module.exports = { password_success: 'पासवर्ड सफलतापूर्वक बदला जा चुका है| कृपया नये पासवर्ड का उपयोग कर लॉग इन करें|', password_wrong_old: 'पुराना पासवर्ड ग़लत है| सहयता के लिए PayDash दल से संपर्क करें|', password_new_nomatch: 'नया पासवर्ड मेल नही ख़ाता|', - password_tooshort: 'आपके नये पासवर्ड की लंबाई कम से कम 6 अक्षर होनी चाहिए|' + password_tooshort: 'आपके नये पासवर्ड की लंबाई कम से कम 6 अक्षर होनी चाहिए|', + password_empty: 'Password cannot be empty', + requesting_change: 'Requesting password change...' + }, + contact: { + contact: 'Contact', + gmail: 'Gmail', + phone: 'Phone' }, whatsapp: { overview:'{name} के लिए मस्टर रोल विवरण\n\n{current_total} मस्टर रोल आज बंद हो रहे हैं\n{delayed_total} मस्टर रोल विलंबित हैं\n\n', @@ -286,7 +308,11 @@ module.exports = { t_5: 'MB नहीं भरी गयी (T+5)', t_6: 'वेज लिस्ट नहीं भेजी गयी (T+6)', t_7: 'FTO पर पहला हस्ताक्षर नहीं हुआ (T+7)', - t_8: 'FTO पर दूसरा हस्ताक्षर नहीं हुआ (T+8)' + t_8: 'FTO पर दूसरा हस्ताक्षर नहीं हुआ (T+8)', + contact: { + phone: 'Phone', + whatsapp: 'WhatsApp' + } }, chart: { days_to_complete_process: 'प्रक्रिया पूरी करने में लगे दिन', @@ -316,30 +342,42 @@ module.exports = { step: 'कदम' } }, + user_dropdown: { + profile: 'प्रोफ़ाइल', + logout: 'लौग आउट' + } profile: { + profile: 'प्रोफ़ाइल', + edit: 'EDIT', + save:'SAVE', + updating:'UPDATING...' firstname: 'मूल नाम', lastname: 'उपनाम', - profile: 'प्रोफ़ाइल', - account: 'अकाउंट', - work_email: 'औपचारिक e-mail', mobile: 'मोबाइल नंबर', personal_email: 'निजी e-mail', - lang : 'भाषा', + work_email: 'औपचारिक e-mail', colorblind: 'Use Colorblind-Safe Theme', - settings: 'सेट्टिंग्स', - logout: 'लौग आउट', - profile_settings: 'आपकी प्रोफ़ाइल सेट्टिंग्स', - email_settings: 'E-Mail सेट्टिंग्स', - primary_email_msg: 'आपके अकाउंट से संबंधित संदेशों और इंटरनेट-संबंधित प्रक्रियाओं के लिए आपके मुख्य e-mail ID का उपयोग किया जाएगा|', - save: 'अद्यतन (update)', - your_primary_email: 'आपका मुख्य e-mail ID', + lang: 'भाषा', + eng: 'English', + hindi: 'Hindi', + change_pass_button: 'पासवर्ड बदलें' + }, + password: { change_pass: 'पासवर्ड बदलें', - old_pass: 'पुराना पासवर्ड ', - new_pass: 'नया पासवर्ड ', - pass_confirm:'नये पासवर्ड को सत्यापित करें', - forgot_pass: 'मैं अपना पासवर्ड भूल गयी/गया' + old_pass: 'पुराना पासवर्ड', + new_pass: 'नया पासवर्ड', + pass_confirm: 'नये पासवर्ड को सत्यापित करें', + forgot_pass: 'मैं अपना पासवर्ड भूल गयी/गया', + change_pass_button: 'पासवर्ड बदलें' }, search: 'Search for Block or Officer Name...', + sort: { + current_total: 'Current total', + delayed_total: 'Delayed total', + days_to_payment: 'Avg. days to payment', + block_name: 'Block name', + ceo_name: 'Block CEO name' + }, messages: { login: { connectivity: 'हमे खेद है कि आप log in करने में विफल रहे| कृपया अपने फ़ोन/कंप्यूटर की internet connectivity को जाँच लें|', @@ -358,7 +396,14 @@ module.exports = { password_success: 'पासवर्ड सफलतापूर्वक बदला जा चुका है| कृपया नये पासवर्ड का उपयोग कर लॉग इन करें|', password_wrong_old: 'पुराना पासवर्ड ग़लत है| सहयता के लिए PayDash दल से संपर्क करें|', password_new_nomatch: 'नया पासवर्ड मेल नही ख़ाता|', - password_tooshort: 'आपके नये पासवर्ड की लंबाई कम से कम 6 अक्षर होनी चाहिए|' + password_tooshort: 'आपके नये पासवर्ड की लंबाई कम से कम 6 अक्षर होनी चाहिए|', + password_empty: 'Password cannot be empty', + requesting_change: 'Requesting password change...' + }, + contact: { + contact: 'Contact', + gmail: 'Gmail', + phone: 'Phone' }, whatsapp: '{name} के लए MGNREGA भुगतान प्रदर्शन\n\n_प्रखंड/जनपद_\n{block_name}\n\nभुगतान प्रक्रिया पूरी करने के लिए औसतन {days_to_payment} दिन लगे\n{current_total} मस्टर रोल आज बंद हो रहे हैं\n{delayed_total} मस्टर रोल विलंबित हैं\n\nविभिन्न पड़ावों पर विलंबित मस्टर रोल\n\n*अटेंडेन्स नहीं भरी गयी (T+2)*\n_कुल मस्टर रोल_\n{t2_total}\n_औसत विलंब_\n{t2_avg}\n\n*MB नहीं भरी गयी (T+5)*\n_कुल मस्टर रोल_\n{t5_total}\n_औसत विलंब_\n{t5_avg}\n\n*वेज लिस्ट नहीं भेजी गयी (T+6)*\n_कुल मस्टर रोल_\n{t6_total}\n_औसत विलंब_\n{t6_avg}\n\n*FTO पर पहला हस्ताक्षर नहीं हुआ (T+7)*\n_कुल मस्टर रोल_\n{t7_total}\n_औसत विलंब_\n{t7_avg}\n\n*FTO पर दूसरा हस्ताक्षर नहीं हुआ (T+8)*\n_कुल मस्टर रोल_\n{t8_total}\n_औसत विलंब_\n{t8_avg}\n' } From 8e8d3b37ea9060084efdda6ded16c998946ef596 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Thu, 25 Aug 2016 13:56:16 -0400 Subject: [PATCH 193/314] Missing commas in translate file --- app/locales/en_US/v2.js | 12 ++++++------ app/locales/hi/v2.js | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/locales/en_US/v2.js b/app/locales/en_US/v2.js index f67ca8a5..227e45c9 100644 --- a/app/locales/en_US/v2.js +++ b/app/locales/en_US/v2.js @@ -219,12 +219,12 @@ module.exports = { user_dropdown: { profile: 'Profile', logout: 'Logout' - } + }, profile: { profile: 'Profile', edit: 'EDIT', save:'SAVE', - updating:'UPDATING...' + updating:'UPDATING...', firstname: 'First Name', lastname: 'Last Name', mobile: 'Mobile', @@ -269,7 +269,7 @@ module.exports = { password_success: 'Password changed successfully. Please login with new password.', password_wrong_old: 'Old password is incorrect. Please contact the PayDash team if you require assistance.', password_new_nomatch: 'New password does not match.', - password_tooshort: 'Your new password must be at least 6 characters long.' + password_tooshort: 'Your new password must be at least 6 characters long.', password_empty: 'Password cannot be empty', requesting_change: 'Requesting password change...' }, @@ -341,12 +341,12 @@ module.exports = { user_dropdown: { profile: 'Profile', logout: 'Logout' - } + }, profile: { profile: 'Profile', edit: 'EDIT', save:'SAVE', - updating:'UPDATING...' + updating:'UPDATING...', firstname: 'First Name', lastname: 'Last Name', mobile: 'Mobile', @@ -392,7 +392,7 @@ module.exports = { password_success: 'Password changed successfully. Please login with new password.', password_wrong_old: 'Old password is incorrect. Please contact the PayDash team if you require assistance.', password_new_nomatch: 'New password does not match.', - password_tooshort: 'Your new password must be at least 6 characters long.' + password_tooshort: 'Your new password must be at least 6 characters long.', password_empty: 'Password cannot be empty', requesting_change: 'Requesting password change...' }, diff --git a/app/locales/hi/v2.js b/app/locales/hi/v2.js index 6767057c..bc386e8f 100644 --- a/app/locales/hi/v2.js +++ b/app/locales/hi/v2.js @@ -223,12 +223,12 @@ module.exports = { user_dropdown: { profile: 'प्रोफ़ाइल', logout: 'लौग आउट' - } + }, profile: { profile: 'प्रोफ़ाइल', edit: 'EDIT', save:'SAVE', - updating:'UPDATING...' + updating:'UPDATING...', firstname: 'मूल नाम', lastname: 'उपनाम', mobile: 'मोबाइल नंबर', @@ -345,12 +345,12 @@ module.exports = { user_dropdown: { profile: 'प्रोफ़ाइल', logout: 'लौग आउट' - } + }, profile: { profile: 'प्रोफ़ाइल', edit: 'EDIT', save:'SAVE', - updating:'UPDATING...' + updating:'UPDATING...', firstname: 'मूल नाम', lastname: 'उपनाम', mobile: 'मोबाइल नंबर', From 571ff98fdb05d33558ab00803a7da35289ea3347 Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Thu, 25 Aug 2016 14:40:52 -0400 Subject: [PATCH 194/314] Add region name to card response. Convert overview to array response --- app/helpers/paydroid_parser.js | 47 +++++++++++++++++++++++++--------- app/helpers/queries.js | 4 +-- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index fbb167b6..81a5c068 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -204,9 +204,23 @@ exports.v2 = function(rows, role) { var versionResponse = D3.values(rows[6]); // Parse the overview response - var current_total = overviewResponse[0].current_total; - var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].days_to_payment; + var overview = D3.nest() + .key(function(d) { + return d.block_code; + }) + .rollup(function(v) { + return { + 'block_code': v[0].block_code, + 'block_name': v[0].block_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'days_to_payment': v[0].days_to_payment + } + }) + .entries(overviewResponse) + .map(function(d) { + return d.values; + }); var state_code = stateResponse[0].state_code; @@ -321,12 +335,7 @@ exports.v2 = function(rows, role) { var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'mrc_prc','tot_trn']; var data = { - 'overview': { - 'current_total': current_total, - 'delayed_total': delayed_total, - 'days_to_payment': days_to_payment, - 'cards_total': cards.length - }, + 'overview': overview, 'cards': cards, 'block_performance': blockPerformance, 'panchayat_performance': panchayatPerformance, @@ -395,9 +404,23 @@ exports.v2 = function(rows, role) { var versionResponse = D3.values(rows[6]); // Parse the overview response - var current_total = overviewResponse[0].current_total; - var delayed_total = overviewResponse[0].delayed_total; - var days_to_payment = overviewResponse[0].days_to_payment; + var overview = D3.nest() + .key(function(d) { + return d.district_code; + }) + .rollup(function(v) { + return { + 'district_code': v[0].district_code, + 'district_name': v[0].district_name, + 'current_total': v[0].current_total, + 'delayed_total': v[0].delayed_total, + 'days_to_payment': v[0].days_to_payment + } + }) + .entries(overviewResponse) + .map(function(d) { + return d.values; + }); var state_code = stateResponse[0].state_code; diff --git a/app/helpers/queries.js b/app/helpers/queries.js index 459bf9bd..b81f1d6e 100644 --- a/app/helpers/queries.js +++ b/app/helpers/queries.js @@ -41,7 +41,7 @@ exports.paydroid = function(USER_ID,ROLE,VERSION) { "SELECT * FROM contact;"; } else if (VERSION===2) { if (ROLE==='block') { - return "SELECT a.current_total, b.delayed_total, c.days_to_payment FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"')) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment, 1 AS merge FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + + return "SELECT a.region_code as block_code, a.region_name as block_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, IFNULL(d.days_to_payment,'No Data') AS days_to_payment FROM (SELECT region_code, region_name FROM user_regions WHERE user_id='"+USER_ID+"') a LEFT JOIN (SELECT count(*) AS current_total, block_code AS region_code FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY region_code) b ON a.region_code = b.region_code LEFT JOIN (SELECT count(*) AS delayed_total, block_code AS region_code FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY region_code) c ON a.region_code = c.region_code LEFT JOIN (SELECT ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1) AS days_to_payment, block_code AS region_code FROM block_delays_duration WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY region_code) d ON a.region_code = d.region_code;" + "SELECT a.staff_id, IFNULL(a.name,'Unmapped') AS name, a.task_assign, IFNULL(a.mobile_no,'Unmapped') AS mobile_no, a.block_code, a.block_name, a.unmapped, b.active, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, b.msr_no, b.work_name, b.work_code, b.panchayat_name, b.end_date, b.days_pending, b.step, b.type FROM (SELECT staff_id, name, task_assign, mobile_no, block_code, block_name, 0 AS unmapped FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") UNION SELECT a.staff_id, a.name, a.task_assign, a.mobile_no, b.block_code, b.block_name, 1 AS unmapped FROM (SELECT NULL as staff_id, NULL as name, NULL as task_assign, NULL as mobile_no, 1 as merge) a RIGHT JOIN (SELECT region_code as block_code, region_name as block_name, 1 as merge FROM user_regions WHERE user_id="+USER_ID+") b ON a.merge = b.merge ) a LEFT JOIN (SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, NULL as days_pending, NULL AS step, 'current_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 2) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code UNION SELECT a.staff_id, 1 AS active, b.block_code, b.msr_no, b.work_name, b.work_code, b.panchayat_name, DATE_FORMAT(b.end_date,'%d-%m-%Y') as end_date, (datediff(CURDATE(), b.end_date) - 5) AS days_pending, b.step, 'delayed_musters' AS type FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code ) b ON a.staff_id=b.staff_id OR (a.staff_id IS NULL AND b.staff_id IS NULL AND a.block_code=b.block_code) LEFT JOIN (SELECT count(*) AS current_total, a.staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a RIGHT JOIN (SELECT * FROM current_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) c ON a.staff_id=c.staff_id OR (a.staff_id IS NULL AND c.staff_id IS NULL AND a.block_code=c.block_code) LEFT JOIN (SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='GRS') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t2') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code UNION SELECT count(*) AS delayed_total, staff_id, b.block_code FROM (SELECT * FROM employees WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND task_assign='TA') a RIGHT JOIN (SELECT * FROM delayed_musters WHERE block_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND step='ds_t5') b ON a.map_location = b.panchayat_code GROUP BY staff_id, b.block_code ) d ON a.staff_id=d.staff_id OR (a.staff_id IS NULL AND d.staff_id IS NULL AND a.block_code=d.block_code) WHERE a.staff_id IS NOT NULL OR (a.staff_id IS NULL AND (c.current_total>0 OR d.delayed_total>0)) ORDER BY active DESC, unmapped, delayed_total DESC, current_total DESC, staff_id;" + "SELECT block_code, block_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc, ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;" + "SELECT block_code, panchayat_code, panchayat_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc, ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM panchayat_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND panchayat_code <> '0000000000' AND block_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), panchayat_code ORDER BY panchayat_code, date;" + @@ -49,7 +49,7 @@ exports.paydroid = function(USER_ID,ROLE,VERSION) { "SELECT * FROM contact;" + "SELECT * FROM paydroid_version;"; } else if (ROLE=='district') { - return "SELECT a.current_total, b.delayed_total, c.days_to_payment FROM (SELECT count(*) AS current_total, 1 AS merge FROM current_musters WHERE block_code IN (SELECT a.block_code FROM blocks a RIGHT JOIN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") b ON a.district_code = b.region_code)) a LEFT JOIN (SELECT count(*) AS delayed_total, 1 AS merge FROM delayed_musters WHERE block_code IN (SELECT a.block_code FROM blocks a RIGHT JOIN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") b ON a.district_code = b.region_code)) b ON a.merge = b.merge LEFT JOIN (SELECT IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment, 1 AS merge FROM district_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH)) c ON b.merge = c.merge;" + + return "SELECT a.region_code as district_code, a.region_name as district_name, IFNULL(b.current_total,0) AS current_total, IFNULL(c.delayed_total,0) AS delayed_total, IFNULL(d.days_to_payment,'No Data') AS days_to_payment FROM (SELECT region_code, region_name FROM user_regions WHERE user_id='"+USER_ID+"') a LEFT JOIN (SELECT count(*) AS current_total, b.district_code AS region_code FROM current_musters a RIGHT JOIN (SELECT district_code, block_code from blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code GROUP BY region_code ) b ON a.region_code = b.region_code LEFT JOIN (SELECT count(*) AS delayed_total, b.district_code AS region_code FROM delayed_musters a RIGHT JOIN (SELECT district_code, block_code from blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code = b.block_code GROUP BY region_code ) c ON a.region_code = c.region_code LEFT JOIN (SELECT ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1) AS days_to_payment, district_code AS region_code FROM district_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY region_code) d ON a.region_code = d.region_code;" + "SELECT a.district_code, a.district_name, a.block_code, a.block_name, j.id, j.username, j.title, j.firstname, j.lastname, IFNULL(j.designation,'No Data') AS designation, IFNULL(j.mobile,'No Data') AS mobile, IFNULL(b.days_to_payment,'No Data') AS days_to_payment, IFNULL(c.current_total,0) AS current_total, IFNULL(d.delayed_total,0) AS delayed_total, IFNULL(e.t2_total,0) AS t2_total, IFNULL(e.t2_avg,'') AS t2_avg, IFNULL(f.t5_total,0) AS t5_total, IFNULL(f.t5_avg,'') AS t5_avg, IFNULL(g.t6_total,0) AS t6_total, IFNULL(g.t6_avg,'') AS t6_avg, IFNULL(h.t7_total,0) AS t7_total, IFNULL(h.t7_avg,'') AS t7_avg, IFNULL(i.t8_total,0) AS t8_total, IFNULL(i.t8_avg,'') AS t8_avg FROM (SELECT district_code, district_name, block_code, block_name FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) a LEFT JOIN (SELECT block_code, IFNULL(ROUND(SUM(mrc_processed_mean * total_transactions) / SUM(total_transactions),1),'No Data') AS days_to_payment FROM block_delays_duration WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") AND gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' and date>=DATE_SUB(now(), INTERVAL 3 MONTH) GROUP BY block_code) b ON a.block_code=b.block_code LEFT JOIN (SELECT b.block_code, count(*) AS current_total FROM current_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) c ON a.block_code=c.block_code LEFT JOIN (SELECT b.block_code, count(*) AS delayed_total FROM delayed_musters a RIGHT JOIN blocks b ON a.block_code=b.block_code AND b.district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+") GROUP BY a.block_code) d ON a.block_code=d.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t2_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 2),1) AS t2_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t2') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) e ON a.block_code=e.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t5_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 5),1) AS t5_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t5') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) f ON a.block_code=f.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t6_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 6),1) AS t6_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t6') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) g ON a.block_code=g.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t7_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 7),1) AS t7_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t7') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) h ON a.block_code=h.block_code LEFT JOIN (SELECT b.block_code, count(*) AS t8_total, ROUND(AVG(datediff(CURDATE(), a.end_date) - 8),1) AS t8_avg FROM (SELECT * FROM delayed_musters WHERE step='ds_t8') a INNER JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.block_code=b.block_code GROUP BY b.block_code) i ON a.block_code=i.block_code LEFT JOIN (SELECT b.block_code, a.id, a.username, a.title, a.firstname, a.lastname, a.designation, a.mobile from users a RIGHT JOIN (SELECT a.user_id, b.block_code FROM user_regions a RIGHT JOIN (SELECT * FROM blocks WHERE district_code IN (SELECT region_code FROM user_regions WHERE user_id="+USER_ID+")) b ON a.region_code = b.block_code) b ON a.id = b.user_id) j ON a.block_code=j.block_code;" + "SELECT district_code, district_name,SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc,ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM district_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), district_code ORDER BY district_code, date;" + "SELECT district_code, block_code, block_name, SUM(total_transactions) AS tot_trn,YEAR(date) AS year, MONTH(date) AS month,ROUND(sum(mrc_mre_mean*total_transactions)/sum(total_transactions),1) mrc_mre,ROUND(sum(mre_wlg_mean*total_transactions)/sum(total_transactions),1) mre_wlg,ROUND(sum(wlg_wls_mean*total_transactions)/sum(total_transactions),1) wlg_wls,ROUND(sum(wls_fto_mean*total_transactions)/sum(total_transactions),1) wls_fto,ROUND(sum(fto_firstsign_mean*total_transactions)/sum(total_transactions),1) fto_sn1,ROUND(sum(firstsign_secondsign_mean*total_transactions)/sum(total_transactions),1) sn1_sn2,ROUND(sum(secondsign_processed_mean*total_transactions)/sum(total_transactions),1) sn2_prc, ROUND(sum(mrc_processed_mean*total_transactions)/sum(total_transactions),1) mrc_prc FROM block_delays_duration WHERE gender = 'both' AND bank_type = 'all' AND date_type = 'processed_date' AND total_transactions > 0 AND district_code IN (SELECT region_code FROM user_regions WHERE user_id='"+USER_ID+"') GROUP BY YEAR(date), MONTH(date), block_code ORDER BY block_code, date;" + From 5f7d814a36a972ffcd4722055064c0ec3fcbe8bb Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Thu, 25 Aug 2016 15:12:02 -0400 Subject: [PATCH 195/314] Update date formatting on charts --- assets/scripts/components/comparison-chart.jsx | 4 ++-- assets/scripts/components/performance-chart.jsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/assets/scripts/components/comparison-chart.jsx b/assets/scripts/components/comparison-chart.jsx index 2511319d..9f562928 100644 --- a/assets/scripts/components/comparison-chart.jsx +++ b/assets/scripts/components/comparison-chart.jsx @@ -66,7 +66,7 @@ const ComparisonChart = React.createClass({ xax_count: 10, // max_x : options.max_x || null, // min_x: options.min_x || null, - xax_format: D3.time.format('%b, %y'), + xax_format: D3.time.format('%b %Y'), chart_type: c_data.length !== 0 ? 'line' : 'missing-data', missing_text: 'No data', show_secondary_x_label: false, @@ -99,7 +99,7 @@ const ComparisonChart = React.createClass({ var l_span = D3.select(legend_target + ' .mg-line' + val.line_id + '-legend-color'); l_span.text(' '); l_span.text('— ' + labels[val.line_id - 1] + ' : ' + prefix.scale(val.value).toFixed(0)); - var format = D3.time.format('%b, %Y'); + var format = D3.time.format('%b %Y'); D3.select('#region_comparison_total_trans').text(format(val.date) + ': ' + val.total_trans); }); }, diff --git a/assets/scripts/components/performance-chart.jsx b/assets/scripts/components/performance-chart.jsx index b8bc50b9..99a35587 100644 --- a/assets/scripts/components/performance-chart.jsx +++ b/assets/scripts/components/performance-chart.jsx @@ -47,7 +47,7 @@ const PerformanceChart = React.createClass({ show_secondary_x_label: false, x_extended_ticks: true, xax_count: 5, - xax_format: D3.time.format('%e %b, %y'), + xax_format: D3.time.format('%b %Y'), decimals: 0, baselines: [{ value: 15, @@ -73,7 +73,7 @@ const PerformanceChart = React.createClass({ l_span.text(' '); var no_days = d.values[index - 1] ? (val.value - d.values[index - 1].value).toFixed(0) : (val.value).toFixed(0); l_span.text('— ' + _this.props.config.labels[val.line_id - 1] + ' : ' + no_days); - var format = D3.time.format('%b %d, %Y'); + var format = D3.time.format('%b %Y'); D3.select('#region_performance_total_trans').text(format(val.date) + ': ' + val.total_trans); }); }, From 82c4b51266cd5610d8ab4bf141861f5e477e904b Mon Sep 17 00:00:00 2001 From: Eric Dodge Date: Fri, 26 Aug 2016 17:35:22 -0400 Subject: [PATCH 196/314] finish changes to overview nest in district api --- app/helpers/paydroid_parser.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/app/helpers/paydroid_parser.js b/app/helpers/paydroid_parser.js index 81a5c068..15be9c97 100644 --- a/app/helpers/paydroid_parser.js +++ b/app/helpers/paydroid_parser.js @@ -526,12 +526,7 @@ exports.v2 = function(rows, role) { var headers = ['date', 'mrc_mre', 'mre_wlg', 'wlg_wls', 'wls_fto', 'fto_sn1', 'sn1_sn2', 'sn2_prc', 'mrc_prc','tot_trn']; var data = { - 'overview': { - 'current_total': current_total, - 'delayed_total': delayed_total, - 'days_to_payment': days_to_payment, - 'cards_total': cards.length - }, + 'overview': overview, 'cards': cards, 'district_performance': districtPerformance, 'block_performance': blockPerformance, From c6b41b53b7d225d8c3c13d738fe8cda0fd0f0b9e Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 26 Aug 2016 09:31:58 +0530 Subject: [PATCH 197/314] Apply Step selection on comparison chart --- .../scripts/components/comparison-chart.jsx | 38 ++++++++----------- .../scripts/components/performance-chart.jsx | 2 +- assets/scripts/lib/region.js | 17 +++++++-- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/assets/scripts/components/comparison-chart.jsx b/assets/scripts/components/comparison-chart.jsx index 9f562928..dfb4538f 100644 --- a/assets/scripts/components/comparison-chart.jsx +++ b/assets/scripts/components/comparison-chart.jsx @@ -5,17 +5,15 @@ import MG from '../lib/mg'; const D3 = require('d3'); const Parser = require('../lib/parser'); +const Region = require('../lib/region'); const ComparisonChart = React.createClass({ - - // comparisonLabels : function(internals) { - // var labels = []; - // internals.active_compare_lines.forEach(function(comparison_line, index) { - // labels.push(internals.data.monthwise[comparison_line][comparison_line + '_name'] + ' ' + internals.data.config.compare_chart_labels[comparison_line]); - // }); - // return labels; - // }, + getInitialState: function(){ + return { + active_step: 1 + }; + }, loadChart: function(){ var _this = this; @@ -27,25 +25,19 @@ const ComparisonChart = React.createClass({ return; } - var comparison_lines = _this.props.config.comparison_lines; + var comparison_lines = _this.props.config.comparison_lines.slice(0); comparison_lines.push(_this.props.activeRegion.region_type); - + comparison_lines.forEach(function(comparison_line, index) { - var region; - if(_this.props.activeRegion.region_type === 'block' && comparison_line ==='block'){ - region = _this.props.performance[_this.props.activeRegion.region_type][_this.props.activeRegion.block_index]; - } - else if(_this.props.activeRegion.region_type === 'panchayat' && comparison_line ==='panchayat'){ - region = _this.props.performance[_this.props.activeRegion.region_type][_this.props.activeRegion.block_index].data[_this.props.activeRegion.panchayat_index]; - }else { - region = _this.props.performance[comparison_line]; - } + var region = Region.find(_this.props.activeRegion, _this.props.performance, comparison_line); + labels.push(region[comparison_line + '_name'] + ' ' + _this.props.config.compare_chart_labels[comparison_line]); + var line_data = Parser.lines({ data: region.data, - col: [1], + col: [_this.state.active_step], isCumulative: false }); if (line_data[0]) { @@ -54,7 +46,6 @@ const ComparisonChart = React.createClass({ }); MG.data_graphic({ - // title: options.title, title: '', target: _this.elem, data: c_data, @@ -118,7 +109,10 @@ const ComparisonChart = React.createClass({ }, stepChange: function(event){ - console.log(event.target.value); + this.setState({ + active_step : event.target.value + }); + this.loadChart(); }, componentDidMount: function() { this.loadChart(); diff --git a/assets/scripts/components/performance-chart.jsx b/assets/scripts/components/performance-chart.jsx index 99a35587..dcc4e49e 100644 --- a/assets/scripts/components/performance-chart.jsx +++ b/assets/scripts/components/performance-chart.jsx @@ -9,7 +9,7 @@ const Parser = require('../lib/parser'); const PerformanceChart = React.createClass({ loadChart: function(){ - + var data; var _this = this; diff --git a/assets/scripts/lib/region.js b/assets/scripts/lib/region.js index 92f18973..301b1479 100644 --- a/assets/scripts/lib/region.js +++ b/assets/scripts/lib/region.js @@ -4,15 +4,15 @@ exports.list = function(performance, role) { var regions = []; if (role === 'block') { - performance['panchayat'].forEach(function(block, block_index){ + performance['panchayat'].forEach(function(block, block_index) { regions.push({ value: block.block_code, label: block.block_name, region_type: 'block', class: 'select_parent', block_index: block_index - }); - block.data.forEach(function(panchayat, panchayat_index){ + }); + block.data.forEach(function(panchayat, panchayat_index) { regions.push({ value: panchayat.panchayat_code, label: panchayat.panchayat_name, @@ -27,3 +27,14 @@ exports.list = function(performance, role) { } return regions; }; + +exports.find = function(activeRegion, performance, comparison_line) { + var region; + if (activeRegion.region_type === 'block' && comparison_line === 'block') { + return region = performance[activeRegion.region_type][activeRegion.block_index]; + } else if (activeRegion.region_type === 'panchayat' && comparison_line === 'panchayat') { + return region = performance[activeRegion.region_type][activeRegion.block_index].data[activeRegion.panchayat_index]; + } else { + return region = performance[comparison_line]; + } +}; From 1e32ca1efb19d0b99a1490cf815c1116baf5be62 Mon Sep 17 00:00:00 2001 From: Ravi Suhag Date: Fri, 26 Aug 2016 12:48:34 +0530 Subject: [PATCH 198/314] Apply translation to overview --- app/locales/en_US/v1.js | 166 +----------------- app/templates/helpers/t.js | 2 - app/templates/overview/overview.hbs | 7 +- .../scripts/components/comparison-chart.jsx | 12 +- 4 files changed, 14 insertions(+), 173 deletions(-) diff --git a/app/locales/en_US/v1.js b/app/locales/en_US/v1.js index caeac190..934d5fe4 100644 --- a/app/locales/en_US/v1.js +++ b/app/locales/en_US/v1.js @@ -2,164 +2,12 @@ module.exports = { $meta: 'English translation file', - profile: { - firstname: 'First Name', - lastname: 'Last Name', - profile: 'Profile', - account: 'Account', - work_email: 'Work Email', - mobile: 'Mobile', - personal_email: 'Personal Email', - lang : 'Language', - settings: 'Settings', - logout: 'Logout', - profile_settings: 'Profile Settings', - email_settings: 'Email Settings', - primary_email_msg: 'Your primary email address will be used for account-related notifications as well as any web-based operations.', - save: 'Update', - your_primary_email: 'Your primary email', - change_pass: 'Change password', - old_pass: 'Old password', - new_pass: 'New password', - pass_confirm:'Verify new password', - forgot_pass: 'I forgot my password' - }, - navigation: { - overview: { - $filter: 'role', - district: 'District Performance', - block: 'Block Performance', - $default: 'Overview Performance' - }, - discrete: { - $filter: 'role', - district: 'Block Performance', - block: 'Panchayat Performance', - $default: 'Discrete Performance' - }, - current: 'Current musters', - delayed: 'Delayed musters' - }, - notifications : { - read : 'Read Notifications', - unread : 'Unread Notifications', - message: { - 1: { - $filter: 'role', - block: [' block made ',' payments to MGNREGA beneficiaries on ',' .'], - district: [' district made ',' payments to MGNREGA beneficiaries on ',' .'] - }, - 2: { - main: ['The average time from muster roll closure to bank processing for these transactions was ',' days, ',' the mandated maximum of 15 days.'], - comparison: ['greater than','equal to','less than'] - } - } - }, - browser_msg: 'The browser you are using is not supported. PayDash works best with Chrome, Firefox, or Internet Explorer 9+.', - messages: { - loading: 'Loading data...', - not_found: 'Page not found. Please contact the PayDash team if you need assistance.' - }, - time_selector: { - '1': 'All available dates', - '2': 'Past 60 days', - '3': 'Past 30 days' - }, - payment_steps: { - '1': 'Muster roll closure to muster roll entry', - '2': 'Muster roll entry to wage list generation', - '3': 'Wage list generation to wage list sent', - '4': 'Wage list sent to FTO generation', - '5': 'FTO generation to first signature', - '6': 'First signature to second signature', - '7': 'Second signature to processed by bank' - }, - payment_steps_labels: [ - 'Muster roll closure to muster roll entry', - 'Muster roll entry to wage list generation', - 'Wage list generation to wage list sent', - 'Wage list sent to FTO generation', - 'FTO generation to first signature', - 'First signature to second signature', - 'Second signature to processed by bank' - ], - compare_chart_labels: { - 'state': 'state average', - 'district': 'district average', - 'block': 'block average', - 'panchayat': 'panchayat average' - }, - y_axis_labels: 'Days to complete process', - total_trans: "Total transactions on", - performance: { + web: { overview: { - chart_a: { - title: { - $filter: 'role', - district: 'District Performance', - block: 'Your Block\'s Performance', - $default: 'Overview Performance' - }, - description: { - $filter: 'role', - district: 'Average number of days to complete each step of the payment process in your district.', - block: 'Average number of days to complete each step of the payment process in your block.', - $default: 'Average number of days to complete each step of the payment process in your region.' - } - }, - chart_b: { - title: { - $filter: 'role', - district: 'Benchmarking Your Performance', - block: 'Benchmarking Your Performance', - $default: 'Benchmarking Your Performance' - }, - description: { - $filter: 'role', - district: 'Compare your performance with averages for your state.', - block: 'Compare your performance with averages for your district and state.', - $default: 'Compare your performance with averages for other regions.' - } - }, - tooltip: 'The chart at right shows the average number of days to complete each step of the payment process for payments that reached beneficiaries’ bank accounts on the given date. Therefore, only completed payments are displayed.', - }, - discrete: { - sub_heading: { - 1: 'Performance of', - 2: 'block/panchayat' - }, - subtitle: { - $filter: 'role', - block: 'The performance of your panchayat on average days to complete each step of the payment process.', - district: 'The performance of your blocks/panchayats on average days to complete each step of the payment process.', - $default: 'The performance of your regions on average days to complete each step of the payment process.' - }, - tooltip: 'The charts below show the average number of days to complete each step of the payment process for payments that reached beneficiaries’ bank accounts on the given date. Therefore, only completed payments are displayed. Your worst performing panchayats are shown first.', - ta_message: 'Your block has unmapped panchayats for the TA designation. As a result, we can\'t show you the performance of all the TA\'s in your block. Please visit the MGNREGA portal at nrega.nic.in to complete your TA mapping.', - grs_message: 'Your block has unmapped panchayats for the GRS designation. As a result, we can\'t show you the performance of all the GRS\'s in your block. Please visit the MGNREGA portal at nrega.nic.in to complete your GRS mapping.', - panchayat_chart_placeholder: 'Select a block or panchayat at left to view its payment performance', - grouping_selectors: { - no: 'No Grouping', - ta: 'Group by TA', - grs: 'Group by GRS' - }, - sidebar : { - total_trans: 'Total Transactions', - avg_days: 'Avg. days from muster roll closure to entry' - } - } - }, - musters: { - current: { - title: 'Musters Closing Today' - }, - delayed: { - title: 'Delayed Musters', - t_2: 'Attendance not filled (T+2)', - t_5: 'Measurement book not filled (T+5)', - t_6: 'Wagelist not sent (T+6)', - t_7: 'Pending for FTO first signature (T+7)', - t_8: 'Pending for FTO second signature (T+8)' + current: 'Current', + delayed: 'Delayed', + days_to_payment: 'Days to payment', + description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' } }, app: { @@ -201,7 +49,7 @@ module.exports = { }, regions: { panchayat: 'Panchayat', - block: 'Block', + block: 'Block', }, tooltip: { date: 'Date', @@ -246,7 +94,7 @@ module.exports = { logout: { connectivity: 'Unable to log out of PayDash. Please try again when your device has internet connectivity.', warning: { - 'message':'Are you sure you want to log out? PayDash offline mode is only available if you stay logged in.', + 'message': 'Are you sure you want to log out? PayDash offline mode is only available if you stay logged in.', 'logout': 'Log out', 'cancel': 'Cancel' }, diff --git a/app/templates/helpers/t.js b/app/templates/helpers/t.js index 96ff4243..9ba7a948 100644 --- a/app/templates/helpers/t.js +++ b/app/templates/helpers/t.js @@ -17,13 +17,11 @@ module.exports = function t(path, credentials, version) { var lang = 'hi'; var criteria = {}; var ver; - if (version) { ver = 'v' + version; } else { ver = 'v1'; } - if (credentials) { criteria.role = credentials.role; lang = credentials.lang; diff --git a/app/templates/overview/overview.hbs b/app/templates/overview/overview.hbs index 02bd0ddd..84e64179 100644 --- a/app/templates/overview/overview.hbs +++ b/app/templates/overview/overview.hbs @@ -4,12 +4,7 @@
    {{credentials.firstname}} {{credentials.lastname}}
    -

    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod - tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, - quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse - cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non - proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    +

    {{t "/web/overview/description" credentials null}}