Skip to content
This repository was archived by the owner on Jul 11, 2023. It is now read-only.

Commit de43dd3

Browse files
committed
Merge pull request #120 from Code4HR/develop
Release!
2 parents f29be76 + 8ca0d60 commit de43dd3

36 files changed

+605
-212
lines changed

api/controllers/Candidate.js

+101-186
Original file line numberDiff line numberDiff line change
@@ -1,177 +1,127 @@
1+
const _ = require('lodash')
2+
13
module.exports = function (server) {
24
const Candidate = server.plugins['hapi-shelf'].model('Candidate')
35
const SurveyAnswer = server.plugins['hapi-shelf'].model('SurveyAnswer')
46

5-
function getCategoryAnswers(surveyResponseId, callback)
7+
function getCandidateMatch(surveyResponseId, callback)
68
{
79
SurveyAnswer
8-
.query(function(answer_builder) {
10+
.query(answer_builder => {
11+
answer_builder.column('survey_response.id as response_id')
12+
answer_builder.column('survey_response.geography_id')
913
answer_builder.column('candidate_answer.candidate_id')
10-
answer_builder.column('question.category_id')
11-
answer_builder.column('question.id as question_id')
14+
answer_builder.column('candidate.candidate_name')
15+
answer_builder.column('candidate_type.id as type_id')
16+
answer_builder.column('candidate_type.type_name ')
17+
answer_builder.column('category.id as category_id')
18+
answer_builder.column('category.category_name')
19+
answer_builder.column('survey_answer.question_id')
1220
answer_builder.column('question.question_text')
13-
answer_builder.column('a2.id as candidate_answer_id')
14-
answer_builder.column('a2.answer_label as candidate_answer_label')
15-
answer_builder.column('a1.id as voter_answer_id')
16-
answer_builder.column('a1.answer_label as voter_answer_text')
17-
answer_builder.innerJoin('answer as a1', 'survey_answer.answer_id', 'a1.id')
21+
answer_builder.column('survey_answer.answer_id')
22+
answer_builder.column('a1.answer_value as answer_text')
23+
answer_builder.column('candidate_answer.answer_id as candidate_answer_id')
24+
answer_builder.column('a2.answer_value as candidate_answer_text')
25+
answer_builder.column(server.plugins['hapi-shelf'].knex.raw("case \
26+
when survey_answer.answer_id = candidate_answer.answer_id \
27+
then (cast(survey_answer.intensity as numeric(3,2)) + cast(candidate_answer.intensity as numeric(3,2))) / 10 \
28+
else 0.00 \
29+
end as score"))
1830
answer_builder.innerJoin('question', 'survey_answer.question_id', 'question.id')
19-
answer_builder.innerJoin('answer as a2', 'question.id', 'a2.question_id')
20-
answer_builder.innerJoin('candidate_answer', 'a2.id', 'candidate_answer.answer_id')
21-
answer_builder.where('survey_answer.survey_response_id', surveyResponseId)
31+
answer_builder.innerJoin('category', 'question.category_id', 'category.id')
32+
answer_builder.innerJoin('answer as a1', 'survey_answer.answer_id', 'a1.id')
33+
answer_builder.innerJoin('survey_response', 'survey_answer.survey_response_id', 'survey_response.id')
34+
answer_builder.innerJoin('candidate_answer', 'survey_answer.question_id', 'candidate_answer.question_id')
35+
answer_builder.innerJoin('answer as a2', 'candidate_answer.answer_id', 'a2.id')
36+
answer_builder.innerJoin('candidate_geography', function() {
37+
this.on('candidate_answer.candidate_id', '=', 'candidate_geography.candidate_id')
38+
.andOn('candidate_geography.geography_id', '=', 'survey_response.geography_id')
39+
})
40+
answer_builder.innerJoin('candidate', 'candidate_answer.candidate_id', 'candidate.id')
41+
answer_builder.innerJoin('candidate_type', 'candidate.candidate_type_id', 'candidate_type.id')
42+
answer_builder.where('survey_response.id', surveyResponseId)
2243
})
2344
.fetchAll()
2445
.then(answers => {
25-
callback(answers)
46+
formatCandidateMatch(answers, callback)
2647
})
2748
}
2849

29-
function getCategoryScores(surveyResponseId, callback)
50+
function formatCandidateMatch(matchArray, callback)
3051
{
31-
var score_raw = 'round((sum(cast(survey_answer.intensity as numeric(3,2)))) / cat_scores.score * 100) as category_score'
52+
var responses = _.uniq(matchArray.pluck('responseId'))
53+
var geographies = _.uniq(matchArray.pluck('geographyId'))
54+
var candidates = _.uniq(matchArray.pluck('candidateId'))
55+
var candidateTypes = _.uniq(matchArray.pluck('typeId'))
56+
var categories = _.uniq(matchArray.pluck('categoryId'))
3257

33-
SurveyAnswer
34-
.query(function(cat_builder) {
35-
cat_builder.column('candidate_answer.candidate_id')
36-
cat_builder.column('category.id as category_id')
37-
cat_builder.column('category.category_name')
38-
cat_builder.column(server.plugins['hapi-shelf'].knex.raw(score_raw))
39-
cat_builder.innerJoin('question', 'survey_answer.question_id', 'question.id')
40-
cat_builder.innerJoin('category', 'question.category_id', 'category.id')
41-
cat_builder.innerJoin('survey_response', 'survey_answer.survey_response_id', 'survey_response.id')
42-
cat_builder.innerJoin('candidate_answer', 'survey_answer.answer_id', 'candidate_answer.answer_id')
43-
cat_builder.innerJoin('candidate_geography', function() {
44-
this.on('candidate_answer.candidate_id', '=', 'candidate_geography.candidate_id')
45-
.andOn('candidate_geography.geography_id', '=', 'survey_response.geography_id')
46-
})
47-
cat_builder.innerJoin('candidate', 'candidate_answer.candidate_id', 'candidate.id')
48-
cat_builder.join(server.plugins['hapi-shelf'].knex.raw(" \
49-
(select question.category_id, category.category_name, sum(sa.intensity) as score \
50-
from survey_answer sa \
51-
inner join question on sa.question_id = question.id \
52-
inner join category on question.category_id = category.id \
53-
where sa.survey_response_id = " + surveyResponseId + " \
54-
group by question.category_id, category.category_name) as cat_scores on category.id = cat_scores.category_id"))
55-
cat_builder.where('survey_response.id', surveyResponseId)
56-
cat_builder.groupBy('candidate_answer.candidate_id', 'category.id', 'category.category_name', 'cat_scores.score')
57-
})
58-
.fetchAll()
59-
.then(categories => {
60-
callback(categories)
61-
})
62-
}
58+
if (responses.length === 1)
59+
{
60+
var output = {}
61+
output.id = responses[0]
62+
output.geographyId = geographies[0]
6363

64-
function formatCandidateMatch(matchArray, categoryArray, answerArray) {
65-
var output = {}
66-
output.id = matchArray[0].attributes.surveyId
67-
output.geographyId = matchArray[0].attributes.geographyId
68-
69-
output.survey = []
70-
71-
matchArray.map(function(match) {
72-
var typeIndex = output.survey.findIndex(type =>
73-
type.candidateTypeName === match.attributes.typeName)
74-
75-
var catIndex = -1
76-
var answerIndex = -1
77-
78-
if(typeIndex === -1)
79-
{
80-
typeIndex = output.survey.push({
81-
candidateTypeId: match.attributes.typeId,
82-
candidateTypeName: match.attributes.typeName,
83-
candidates: [{
84-
candidateId: match.attributes.candidateId,
85-
candidateName: match.attributes.candidateName,
86-
compositeMatchScore: match.attributes.compositeScore,
87-
categoryMatchScores: []
88-
}]
89-
})-1
90-
91-
categoryArray.map(function(category) {
92-
if (match.attributes.candidateId === category.attributes.candidateId)
64+
output.survey = candidateTypes.map((typeId) => {
65+
var candidateType = {}
66+
67+
candidateType.candidateTypeId = typeId
68+
candidateType.candidateTypeName = matchArray.findWhere({'typeId': typeId}).get('typeName')
69+
70+
candidateType.candidates = candidates.map((candidateId) => {
71+
var candidateList = matchArray.where({'typeId': typeId, 'candidateId': candidateId})
72+
73+
if (candidateList)
9374
{
94-
catIndex = output.survey[typeIndex].candidates[0].categoryMatchScores.findIndex(candCat =>
95-
candCat.categoryId === category.attributes.categoryId)
96-
97-
if (catIndex === -1)
98-
{
99-
catIndex = output.survey[typeIndex].candidates[0].categoryMatchScores.push({
100-
categoryId: category.attributes.categoryId,
101-
categoryName: category.attributes.categoryName,
102-
categoryMatch: category.attributes.categoryScore,
103-
questions: []
104-
})-1
105-
}
106-
107-
answerArray.map(function(answer) {
108-
if(match.attributes.candidateId === answer.attributes.candidateId
109-
&& category.attributes.categoryId === answer.attributes.categoryId)
110-
{
111-
output.survey[typeIndex].candidates[0].categoryMatchScores[catIndex].questions.push({
112-
questionId: answer.attributes.questionId,
113-
questionText: answer.attributes.questionText,
114-
candidateAnswerId: answer.attributes.candidateAnswerId,
115-
candidateAnswerLabel: answer.attributes.candidateAnswerLabel,
116-
voterAnswerId: answer.attributes.voterAnswerId,
117-
voterAnswerText: answer.attributes.voterAnswerText
118-
})
119-
}
75+
var candidate = {}
76+
77+
candidate.candidateId = candidateId
78+
candidate.candidateName = matchArray.findWhere({'candidateId': candidateId}).get('candidateName')
79+
candidate.compositeMatchScore = Math.round((candidateList.reduce((p, n) => {
80+
return p + parseFloat(n.get('score'))
81+
}, 0.0)*100) / (candidateList.length))
82+
83+
candidate.categoryMatchScores = categories.map((categoryId) => {
84+
var categoryList = matchArray.where({'typeId': typeId,
85+
'categoryId': categoryId,
86+
'candidateId': candidateId})
87+
88+
if (categoryList)
89+
{
90+
var category = {}
91+
92+
category.categoryId = categoryId
93+
category.categoryName = matchArray.findWhere({'categoryId': categoryId}).get('categoryName')
94+
category.categoryMatch = Math.round((categoryList.reduce((p, n) => {
95+
return p + parseFloat(n.get('score'))
96+
}, 0.0)*100) / categoryList.length)
97+
98+
category.questions = categoryList.map((item) => {
99+
return {
100+
questionId: item.get('questionId'),
101+
questionText: item.get('questionText'),
102+
candidateAnswerId: item.get('candidateAnswerId'),
103+
candidateAnswerLabel: item.get('candidateAnswerText'),
104+
voterAnswerId: item.get('answerId'),
105+
voterAnswerText: item.get('answerText')
106+
}
107+
})
108+
109+
return category
110+
}
120111
})
112+
113+
return candidate
121114
}
122115
})
123-
} else {
124-
var candIndex = output.survey[typeIndex].candidates.findIndex(cand =>
125-
cand.candidateId === match.attributes.candidateId)
126-
127-
if (candIndex === -1)
128-
{
129-
candIndex = output.survey[typeIndex].candidates.push({
130-
candidateId: match.attributes.candidateId,
131-
candidateName: match.attributes.candidateName,
132-
compositeMatchScore: match.attributes.compositeScore,
133-
categoryMatchScores: []
134-
})-1
135-
136-
categoryArray.map(function(category) {
137-
if (match.attributes.candidateId === category.attributes.candidateId)
138-
{
139-
catIndex = output.survey[typeIndex].candidates[candIndex].categoryMatchScores.findIndex(candCat =>
140-
candCat.categoryId === category.attributes.categoryId)
141-
142-
if (catIndex === -1)
143-
{
144-
catIndex = output.survey[typeIndex].candidates[candIndex].categoryMatchScores.push({
145-
categoryId: category.attributes.categoryId,
146-
categoryName: category.attributes.categoryName,
147-
categoryMatch: category.attributes.categoryScore,
148-
questions: []
149-
})-1
150-
}
151-
152-
answerArray.map(function(answer) {
153-
if(match.attributes.candidateId === answer.attributes.candidateId
154-
&& category.attributes.categoryId === answer.attributes.categoryId)
155-
{
156-
output.survey[typeIndex].candidates[candIndex].categoryMatchScores[catIndex].questions.push({
157-
questionId: answer.attributes.questionId,
158-
questionText: answer.attributes.questionText,
159-
candidateAnswerId: answer.attributes.candidateAnswerId,
160-
candidateAnswerLabel: answer.attributes.candidateAnswerLabel,
161-
voterAnswerId: answer.attributes.voterAnswerId,
162-
voterAnswerText: answer.attributes.voterAnswerText
163-
})
164-
}
165-
})
166-
}
167-
})
168-
}
169-
}
170-
})
171116

172-
return(output)
117+
return candidateType
118+
})
119+
}
120+
121+
callback(output)
173122
}
174123

124+
175125
return [{
176126
method: 'GET',
177127
path: '/api/candidate',
@@ -199,43 +149,8 @@ module.exports = function (server) {
199149
method: 'GET',
200150
path: '/api/candidate_match/{survey_response_id}',
201151
handler: (request, reply) => {
202-
SurveyAnswer
203-
.query(function(score_builder) {
204-
score_builder.sum('intensity as score');
205-
score_builder.where('survey_response_id', request.params.survey_response_id)
206-
})
207-
.fetch()
208-
.then(function(total) {
209-
var score_raw = 'round((sum(cast(survey_answer.intensity as numeric(3,2))) / '
210-
+ total.attributes.score + ') * 100) as composite_score'
211-
212-
SurveyAnswer
213-
.query(function(match_builder) {
214-
match_builder.column('survey_response.id as survey_id', 'survey_response.geography_id')
215-
match_builder.column('candidate_answer.candidate_id', 'candidate.candidate_name')
216-
match_builder.column('candidate_type.id as type_id', 'candidate_type.type_name')
217-
match_builder.column(server.plugins['hapi-shelf'].knex.raw(score_raw))
218-
match_builder.innerJoin('survey_response', 'survey_answer.survey_response_id', 'survey_response.id')
219-
match_builder.innerJoin('candidate_answer', 'survey_answer.answer_id', 'candidate_answer.answer_id')
220-
match_builder.innerJoin('candidate_geography', function() {
221-
this.on('candidate_answer.candidate_id', '=', 'candidate_geography.candidate_id')
222-
.andOn('candidate_geography.geography_id', '=', 'survey_response.geography_id')
223-
})
224-
match_builder.innerJoin('candidate', 'candidate_answer.candidate_id', 'candidate.id')
225-
match_builder.innerJoin('candidate_type', 'candidate.candidate_type_id', 'candidate_type.id')
226-
match_builder.where('survey_response.id', request.params.survey_response_id)
227-
match_builder.groupBy('survey_response.id', 'survey_response.geography_id'
228-
, 'candidate_answer.candidate_id', 'candidate.candidate_name'
229-
, 'candidate_type.id', 'candidate_type.type_name')
230-
})
231-
.fetchAll()
232-
.then(matches => {
233-
getCategoryScores(request.params.survey_response_id, function(categories) {
234-
getCategoryAnswers(request.params.survey_response_id, function(answers) {
235-
reply(formatCandidateMatch(matches.models, categories.models, answers.models))
236-
})
237-
})
238-
})
152+
getCandidateMatch(request.params.survey_response_id, (matches) => {
153+
reply(matches)
239154
})
240155
}
241156
}]

assets/img/candidates/alexander.jpg

30.2 KB
Loading

assets/img/candidates/candela.jpg

35.9 KB
Loading

assets/img/candidates/cook.jpg

31.3 KB
Loading

assets/img/candidates/graves.jpg

32.2 KB
Loading

assets/img/candidates/mccabe.jpg

23 KB
Loading

assets/img/candidates/mcclellan.jpg

28.8 KB
Loading
332 KB
Loading
993 KB
Loading
21 KB
Loading
145 KB
Loading
12.8 KB
Loading
213 KB
Loading
397 KB
Loading
24.3 KB
Loading
6.08 KB
Loading
131 KB
Loading

assets/img/candidates/protogyrou.jpg

39.4 KB
Loading

assets/img/candidates/stewart.jpg

20.9 KB
Loading

assets/img/candidates/turner.jpg

23.3 KB
Loading

assets/img/candidates/winn.jpg

37.7 KB
Loading

0 commit comments

Comments
 (0)