[IMP] moved prepare_result and get_input_summary to the model from controller and some other improvements

bzr revid: dizzy.zala@gmail.com-20140403104637-dpqi4euo5czy3rsk
This commit is contained in:
Dharmraj Jhala (OpenERP) 2014-04-03 16:16:37 +05:30
parent 4224b70a76
commit 4e2942d418
3 changed files with 132 additions and 121 deletions

View File

@ -22,9 +22,7 @@
import json
import logging
import werkzeug
from collections import Counter
from datetime import datetime
from itertools import product
from math import ceil
from openerp import SUPERUSER_ID
@ -305,16 +303,19 @@ class WebsiteSurvey(http.Controller):
})
def prepare_result_dict(self,survey, current_filters=[]):
"""Returns dictionary having values for rendering template"""
survey_obj = request.registry['survey.survey']
result = {'survey':survey, 'page_ids': []}
for page in survey.page_ids:
page_dict = {'page': page, 'question_ids': []}
for question in page.question_ids:
question_dict = { 'question':question, 'input_summary':self.get_input_summary(question, current_filters),'prepare_result':self.prepare_result(question, current_filters)}
question_dict = { 'question':question, 'input_summary':survey_obj.get_input_summary(request.cr, request.uid, question, current_filters, context=request.context),'prepare_result':survey_obj.prepare_result(request.cr, request.uid, question, current_filters, context=request.context)}
page_dict['question_ids'].append(question_dict)
result['page_ids'].append(page_dict)
return result
def get_filter_data(self, post):
"""Returns data used for filtering the result"""
filters = []
#if user add some random data in query URI
try:
@ -331,66 +332,21 @@ class WebsiteSurvey(http.Controller):
total = ceil(total_record / float(limit))
return range(1, int(total + 1))
def prepare_result(self, question, current_filters=[]):
'''Prepare statistical data for questions by counting number of vote per choice on basis of filter'''
#Calculate and return statistics for choice
if question.type in ['simple_choice', 'multiple_choice']:
result_summary = {}
[result_summary.update({label.id: {'text': label.value, 'count': 0, 'answer_id': label.id}}) for label in question.labels_ids]
for input_line in question.user_input_line_ids:
if result_summary.get(input_line.value_suggested.id) and (not(current_filters) or input_line.user_input_id.id in current_filters):
result_summary[input_line.value_suggested.id]['count'] += 1
result_summary = result_summary.values()
#Calculate and return statistics for matrix
if question.type == 'matrix':
rows, answers, res = {}, {}, {}
[rows.update({label.id: label.value}) for label in question.labels_ids_2]
[answers.update({label.id: label.value}) for label in question.labels_ids]
for cell in product(rows.keys(), answers.keys()):
res[cell] = 0
for input_line in question.user_input_line_ids:
if not(current_filters) or input_line.user_input_id.id in current_filters:
res[(input_line.value_suggested_row.id, input_line.value_suggested.id)] += 1
result_summary = {'answers': answers, 'rows': rows, 'result': res}
#Calculate and return statistics for free_text, textbox, datetime
if question.type in ['free_text', 'textbox', 'datetime']:
result_summary = []
for input_line in question.user_input_line_ids:
if not(current_filters) or input_line.user_input_id.id in current_filters:
result_summary.append(input_line)
#Calculate and return statistics for numerical_box
if question.type == 'numerical_box':
result_summary = {'input_lines': []}
all_inputs = []
for input_line in question.user_input_line_ids:
if not(current_filters) or input_line.user_input_id.id in current_filters:
all_inputs.append(input_line.value_number)
result_summary['input_lines'].append(input_line)
result_summary.update({'average': round(sum(all_inputs) / len(all_inputs), 2),
'max': round(max(all_inputs), 2),
'min': round(min(all_inputs), 2),
'most_comman': Counter(all_inputs).most_common(5)})
return result_summary
@http.route(['/survey/results/graph/<int:question>'],
type='http', auth='user', multilang=True, website=True)
def get_graph_data(self, question, **post):
'''Returns appropriate formated data required by graph library on basis of filter'''
question = request.registry['survey.question'].browse(request.cr, request.uid, question)
survey_obj = request.registry['survey.survey']
current_filters = safe_eval(post.get('current_filters', '[]'))
result = []
if question.type == 'multiple_choice':
result.append({'key': str(question.question),
'values': self.prepare_result(question, current_filters)})
'values': survey_obj.prepare_result(request.cr, request.uid, question, current_filters, context=request.context)})
if question.type == 'simple_choice':
result = self.prepare_result(question, current_filters)
result = survey_obj.prepare_result(request.cr, request.uid, question, current_filters, context=request.context)
if question.type == 'matrix':
data = self.prepare_result(question, current_filters)
data = survey_obj.prepare_result(request.cr, request.uid, question, current_filters, context=request.context)
for answer in data['answers']:
values = []
for res in data['result']:
@ -399,21 +355,6 @@ class WebsiteSurvey(http.Controller):
result.append({'key': data['answers'].get(answer), 'values': values})
return json.dumps(result)
def get_input_summary(self, question, current_filters=[]):
'''Returns overall summary of question e.g. answered, skipped, total_inputs on basis of filter'''
result = {}
if question.survey_id.user_input_ids:
total_input_ids = current_filters or [input_id.id for input_id in question.survey_id.user_input_ids if input_id.state != 'new']
result['total_inputs'] = len(total_input_ids)
question_input_ids = []
for user_input in question.user_input_line_ids:
if not user_input.skipped:
question_input_ids.append(user_input.user_input_id.id)
result['answered'] = len(set(question_input_ids) & set(total_input_ids))
result['skipped'] = result['total_inputs'] - result['answered']
return result
def dict_soft_update(dictionary, key, value):
''' Insert the pair <key>: <value> into the <dictionary>. If <key> is
already present, this function will append <value> to the list of

View File

@ -24,6 +24,8 @@ from openerp.tools.translate import _
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT as DF
from openerp.addons.website.models.website import slug
from urlparse import urljoin
from itertools import product
from collections import Counter
import datetime
import logging
@ -185,6 +187,74 @@ class survey_survey(osv.Model):
labels = label_obj.browse(cr, uid, [row_id, answer_id], context=context)
filter_display_data.append({'question_text': question.question, 'labels': [label.value for label in labels]})
return filter_display_data
def prepare_result(self, cr, uid, question, current_filters=[], context=None):
'''Prepare statistical data for questions by counting number of vote per choice on basis of filter
:param question: browsed record of survey.question
'''
if context is None:
context = {}
#Calculate and return statistics for choice
if question.type in ['simple_choice', 'multiple_choice']:
result_summary = {}
[result_summary.update({label.id: {'text': label.value, 'count': 0, 'answer_id': label.id}}) for label in question.labels_ids]
for input_line in question.user_input_line_ids:
if result_summary.get(input_line.value_suggested.id) and (not(current_filters) or input_line.user_input_id.id in current_filters):
result_summary[input_line.value_suggested.id]['count'] += 1
result_summary = result_summary.values()
#Calculate and return statistics for matrix
if question.type == 'matrix':
rows, answers, res = {}, {}, {}
[rows.update({label.id: label.value}) for label in question.labels_ids_2]
[answers.update({label.id: label.value}) for label in question.labels_ids]
for cell in product(rows.keys(), answers.keys()):
res[cell] = 0
for input_line in question.user_input_line_ids:
if not(current_filters) or input_line.user_input_id.id in current_filters:
res[(input_line.value_suggested_row.id, input_line.value_suggested.id)] += 1
result_summary = {'answers': answers, 'rows': rows, 'result': res}
#Calculate and return statistics for free_text, textbox, datetime
if question.type in ['free_text', 'textbox', 'datetime']:
result_summary = []
for input_line in question.user_input_line_ids:
if not(current_filters) or input_line.user_input_id.id in current_filters:
result_summary.append(input_line)
#Calculate and return statistics for numerical_box
if question.type == 'numerical_box':
result_summary = {'input_lines': []}
all_inputs = []
for input_line in question.user_input_line_ids:
if not(current_filters) or input_line.user_input_id.id in current_filters:
all_inputs.append(input_line.value_number)
result_summary['input_lines'].append(input_line)
if all_inputs:
result_summary.update({'average': round(sum(all_inputs) / len(all_inputs), 2),
'max': round(max(all_inputs), 2),
'min': round(min(all_inputs), 2),
'most_comman': Counter(all_inputs).most_common(5)})
return result_summary
def get_input_summary(self, cr, uid, question, current_filters=[], context=None):
'''Returns overall summary of question e.g. answered, skipped, total_inputs on basis of filter
:param question: browsed record of survey.question
'''
if context is None:
context = {}
result = {}
if question.survey_id.user_input_ids:
total_input_ids = current_filters or [input_id.id for input_id in question.survey_id.user_input_ids if input_id.state != 'new']
result['total_inputs'] = len(total_input_ids)
question_input_ids = []
for user_input in question.user_input_line_ids:
if not user_input.skipped:
question_input_ids.append(user_input.user_input_id.id)
result['answered'] = len(set(question_input_ids) & set(total_input_ids))
result['skipped'] = result['total_inputs'] - result['answered']
return result
# Model fields #
_columns = {

View File

@ -29,12 +29,12 @@
</span>
</t>
<t t-if="filter_finish == False">
<span class="label label-primary only_left_radius filter-all">
All surveys
</span>
<span class="label label-default only_right_radius filter-finished">
Finished surveys
</span>
<span class="label label-primary only_left_radius filter-all">
All surveys
</span>
<span class="label label-default only_right_radius filter-finished">
Finished surveys
</span>
</t>
</small>
<small t-if="filter_display_data" class="pull-right clear_survey_filter"> <i class="fa fa-times"></i> Clear All Filters</small></h3>
@ -62,20 +62,25 @@
<span class="label label-danger"><span t-esc="input_summary['skipped']"></span> Skipped</span>
</span>
</h4>
<t t-if="question.description">
<h5><span class="text-muted" t-field="question.description"></span></h5>
<t t-if="input_summary['answered'] != 0">
<t t-if="question.description">
<h5><span class="text-muted" t-field="question.description"></span></h5>
</t>
<t t-if="question.type in ['textbox', 'free_text', 'datetime']">
<t t-call="survey.result_text"></t>
</t>
<t t-if="question.type in ['simple_choice', 'multiple_choice']">
<t t-call="survey.result_choice"></t>
</t>
<t t-if="question.type == 'matrix'">
<t t-call="survey.result_matrix"></t>
</t>
<t t-if="question.type == 'numerical_box'">
<t t-call="survey.result_number"></t>
</t>
</t>
<t t-if="question.type in ['textbox', 'free_text', 'datetime']">
<t t-call="survey.result_text"></t>
</t>
<t t-if="question.type in ['simple_choice', 'multiple_choice']">
<t t-call="survey.result_choice"></t>
</t>
<t t-if="question.type == 'matrix'">
<t t-call="survey.result_matrix"></t>
</t>
<t t-if="question.type == 'numerical_box'">
<t t-call="survey.result_number"></t>
<t t-if="input_summary['answered'] == 0">
<h2 style="padding-top:30px;padding-bottom:30px;text-align:center;" class="text-muted">Sorry, No one answered this question.</h2>
</t>
</div>
</div>
@ -86,41 +91,36 @@
<!-- Result for free_text,textbox and datetime -->
<template id="result_text" name="Text Result">
<t t-if="input_summary['answered'] != 0">
<table class="table table-hover table-condensed" t-att-id="'table_question_%d' % question.id">
<thead>
<tr>
<th>#</th>
<th>User Responses</th>
</tr>
</thead>
<tbody>
<t t-set="text_result" t-value="prepare_result"/>
<tr class="hidden" t-foreach="text_result" t-as="user_input">
<td><a t-att-href="'%s/%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)"><t t-esc="user_input_index+1"></t></a></td>
<t t-if="question.type == 'free_text'">
<td>
<span t-field="user_input.value_free_text"></span><br/>
</td>
</t>
<t t-if="question.type == 'textbox'">
<td>
<span t-field="user_input.value_text"></span><br/>
</td>
</t>
<t t-if="question.type == 'datetime'">
<td>
<span class="oe_date" t-field="user_input.value_date"></span><br/>
</td>
</t>
</tr>
</tbody>
</table>
<t t-call="survey.pagination" />
</t>
<t t-if="input_summary['answered'] == 0">
<h2 style="padding-top:30px;padding-bottom:30px;text-align:center;" class="text-muted">Sorry, No one answered this question.</h2>
</t>
<table class="table table-hover table-condensed" t-att-id="'table_question_%d' % question.id">
<thead>
<tr>
<th>#</th>
<th>User Responses</th>
</tr>
</thead>
<tbody>
<t t-set="text_result" t-value="prepare_result"/>
<tr class="hidden" t-foreach="text_result" t-as="user_input">
<td><a t-att-href="'%s/%s' % (user_input.user_input_id.print_url, user_input.user_input_id.token)"><t t-esc="user_input_index+1"></t></a></td>
<t t-if="question.type == 'free_text'">
<td>
<span t-field="user_input.value_free_text"></span><br/>
</td>
</t>
<t t-if="question.type == 'textbox'">
<td>
<span t-field="user_input.value_text"></span><br/>
</td>
</t>
<t t-if="question.type == 'datetime'">
<td>
<span class="oe_date" t-field="user_input.value_date"></span><br/>
</td>
</t>
</tr>
</tbody>
</table>
<t t-call="survey.pagination" />
</template>
<!-- Result for simple_choice and multiple_choice -->