[IMP] Survey Kanban view

[REM] Unused code in survey.py

[REF] Code cleaning

bzr revid: rim@openerp.com-20131129084914-z76feeg813q38l25
This commit is contained in:
Richard Mathot (OpenERP) 2013-11-29 09:49:14 +01:00
parent 92b55fe2a5
commit 65c9704954
9 changed files with 137 additions and 124 deletions

View File

@ -20,3 +20,5 @@
##############################################################################
import main
# vim: exp and tab: smartindent: tabstop=4: softtabstop=4: shiftwidth=4:

View File

@ -22,7 +22,6 @@
from openerp.addons.web import http
from openerp.addons.web.http import request
from openerp.addons.website.models import website
from openerp.osv import fields
from openerp import SUPERUSER_ID
import werkzeug
@ -37,22 +36,22 @@ class WebsiteSurvey(http.Controller):
# Survey list
@website.route(['/survey/',
'/survey/list/'],
type='http', auth='public', multilang=True)
'/survey/list/'],
type='http', auth='public', multilang=True)
def list_surveys(self, **post):
'''Lists all the public surveys'''
cr, uid, context = request.cr, request.uid, request.context
survey_obj = request.registry['survey.survey']
survey_ids = survey_obj.search(cr, uid, [('state', '=', 'open'),
('page_ids', '!=', 'None')],
context=context)
('page_ids', '!=', 'None')],
context=context)
surveys = survey_obj.browse(cr, uid, survey_ids, context=context)
return request.website.render('survey.list', {'surveys': surveys})
# Survey start
@website.route(['/survey/start/<model("survey.survey"):survey>',
'/survey/start/<model("survey.survey"):survey>/<string:token>'],
type='http', auth='public', multilang=True)
type='http', auth='public', multilang=True)
def start_survey(self, survey, token=None, **post):
cr, uid, context = request.cr, request.uid, request.context
survey_obj = request.registry['survey.survey']
@ -220,28 +219,13 @@ class WebsiteSurvey(http.Controller):
else:
# Store answers into database
user_input_obj = request.registry['survey.user_input']
user_input_line_obj = request.registry['survey.user_input_line']
try:
user_input_id = user_input_obj.search(cr, uid, [('token', '=', post['token'])], context=context)[0]
except KeyError: # Invalid token
return request.website.render("website.403")
user_input_obj.write(cr, uid, [user_input_id], {'state': 'skip'}, context=context)
for question in questions:
answer_tag = "%s_%s_%s" % (survey.id, page_id, question.id)
vals = {
'user_input_id': user_input_id,
'question_id': question.id,
'page_id': page_id,
'survey_id': survey.id,
}
if answer_tag in post:
if question.type == 'textbox':
vals.update({'answer_type': 'text', 'value_text': post[answer_tag]})
pass
else:
vals.update({'skipped': True})
user_input_line_obj.create(cr, uid, vals, context=context)
user_input_obj.save_lines(cr, uid, user_input_id, question, post, answer_tag, context=context)
ret['redirect'] = '/survey/fill/%s/%s' % (survey.id, post['token'])
return json.dumps(ret)
@ -282,7 +266,7 @@ class WebsiteSurvey(http.Controller):
try:
checker = getattr(self, 'validate_' + question.type)
except AttributeError:
_logger.warning(question.type + ": This type of question has no validation method")
_logger.error(question.type + ": This type of question has no validation method")
return {}
else:
return checker(question, post, answer_tag)
@ -403,11 +387,4 @@ class WebsiteSurvey(http.Controller):
# problems = []
# return problems
def dict_keys_startswith(self, dictionary, string):
'''Returns a dictionary containing the elements of <dict> whose keys start
with <string>.
.. note::
This function uses dictionary comprehensions (Python >= 2.7)'''
return {k: dictionary[k] for k in filter(lambda key: key.startswith(string), dictionary.keys())}
# vim: exp and tab: smartindent: tabstop=4: softtabstop=4: shiftwidth=4:

View File

@ -13,7 +13,7 @@
}
.openerp .oe_kanban_survey .oe_kanban_status,
.openerp .oe_kanban_survey .oe_kanban_status_green,
.openerp .oe_kanban_survey .oe_kanban_status_darkgreen,
.openerp .oe_kanban_survey .oe_kanban_status_salmon,
.openerp .oe_kanban_survey .oe_kanban_status_red {
display: block;
height: 10px;
@ -25,8 +25,8 @@
.openerp .oe_kanban_survey .oe_kanban_status_green {
background-color: green;
}
.openerp .oe_kanban_survey .oe_kanban_status_darkgreen {
background-color: darkgreen;
.openerp .oe_kanban_survey .oe_kanban_status_salmon {
background-color: salmon;
}
.openerp .oe_kanban_survey .oe_kanban_status_red {
background-color: red;
@ -34,3 +34,12 @@
.openerp .oe_kanban_survey .oe_inactive {
color: #aaaaaa;
}
.openerp .oe_kanban_survey .oe_stats_box {
width: 100px;
display: inline-block;
margin: 2px 5px 0px 5px;
text-align: center;
border: 1px solid rgba(0, 0, 0, 0.16);
background-color: #FFFFFF;
}

View File

@ -1,3 +1,21 @@
/*
* OpenERP, Open Source Management Solution
* Copyright (C) 2004-TODAY OpenERP S.A. <http://www.openerp.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
$(document).ready(function () {
console.debug("[survey] Custom JS for survey is loading...");

View File

@ -19,10 +19,14 @@
#
##############################################################################
from urlparse import urljoin
from openerp.osv import fields, osv
from openerp.tools.translate import _
from urlparse import urljoin
import uuid
import logging
_logger = logging.getLogger(__name__)
class survey_survey(osv.osv):
@ -251,16 +255,6 @@ class survey_survey(osv.osv):
pass
return super(survey_survey, self).write(cr, uid, ids, vals, context=None)
# def unlink(self, cr, uid, ids, context=None):
# ''' Delete survey and linked email templates (if any) '''
# email_template_ids = list()
# for survey in self.browse(cr, uid, ids, context=context):
# email_template_ids.append(survey.email_template_id.id)
# if email_template_ids:
# self.pool.get('email.template').unlink(cr, uid, email_template_ids,
# context=context)
# return super(survey_survey, self).unlink(cr, uid, ids, context=context)
class survey_page(osv.osv):
'''A page for a survey.
@ -293,21 +287,6 @@ class survey_page(osv.osv):
# Public methods #
# def survey_save(self, cr, uid, ids, context=None):
# if context is None:
# context = {}
# surv_name_wiz = self.pool.get('survey.question.wiz')
# surv_name_wiz.write(cr, uid, [context.get('wizard_id', False)],
# {'transfer': True, 'page_no': context.get('page_number', 0)})
# return {
# 'view_type': 'form',
# 'view_mode': 'form',
# 'res_model': 'survey.question.wiz',
# 'type': 'ir.actions.act_window',
# 'target': 'new',
# 'context': context
# }
def copy(self, cr, uid, ids, default=None, context=None):
vals = {}
current_rec = self.read(cr, uid, ids, context=context)
@ -371,7 +350,7 @@ class survey_question(osv.osv):
'Number of columns'),
'display_mode': fields.selection([('columns', 'Columns'),
('dropdown', 'Dropdown menu')],
'Display mode'),
'Display mode'),
# Comments
'comments_allowed': fields.boolean('Allow comments',
@ -391,7 +370,7 @@ class survey_question(osv.osv):
('is_decimal', 'Must be a decimal number'),
#('is_date', 'Must be a date'),
('is_email', 'Must be an email address')],
'Validation type'),
'Validation type', translate=True),
'validation_length_min': fields.integer('Minimum length'),
'validation_length_max': fields.integer('Maximum length'),
'validation_min_float_value': fields.float('Minimum value'),
@ -400,7 +379,9 @@ class survey_question(osv.osv):
'validation_max_int_value': fields.integer('Maximum value'),
'validation_min_date': fields.date('Start date range'),
'validation_max_date': fields.date('End date range'),
'validation_error_msg': fields.char("Error message", oldname='validation_valid_err_msg'),
'validation_error_msg': fields.char('Error message',
oldname='validation_valid_err_msg',
translate=True),
# Constraints on number of answers
'constr_mandatory': fields.boolean('Mandatory question',
@ -440,13 +421,6 @@ class survey_question(osv.osv):
('validation_date', 'CHECK (validation_min_date <= validation_max_date)', 'Max date cannot be smaller than min date!')
]
def on_change_page_id(self, cr, uid, ids, page_id, context=None):
if page_id:
page = self.pool.get('survey.page').browse(cr, uid, page_id,
context=context)
return {'survey_id': page.survey_id and page.survey_id.id}
return {'value': {}}
# def write(self, cr, uid, ids, vals, context=None):
# questions = self.read(cr, uid, ids, ['answer_choice_ids', 'type',
# 'required_type', 'req_ans', 'minimum_req_ans', 'maximum_req_ans',
@ -577,18 +551,20 @@ class survey_user_input(osv.osv):
_columns = {
'survey_id': fields.many2one('survey.survey', 'Survey', required=True,
readonly=1, ondelete='restrict'),
readonly=1, ondelete='restrict'),
'date_create': fields.datetime('Creation Date', required=True,
readonly=1),
readonly=1),
'deadline': fields.date("Deadline",
help="Date by which the person can take part to the survey",
oldname="date_deadline"),
help="Date by which the person can take part to the survey",
oldname="date_deadline"),
'type': fields.selection([('manually', 'Manually'), ('link', 'Link')],
'Answer Type', required=1, readonly=1, oldname="response_type"),
'Answer Type', required=1, readonly=1,
oldname="response_type"),
'state': fields.selection([('new', 'Not started yet'),
('skip', 'Partially completed'),
('done', 'Completed')], 'Status',
readonly=True),
('skip', 'Partially completed'),
('done', 'Completed')],
'Status',
readonly=True),
'test_entry': fields.boolean('Test entry', readonly=1),
'token': fields.char("Identification token", readonly=1, required=1),
@ -598,7 +574,7 @@ class survey_user_input(osv.osv):
# The answers !
'user_input_line_ids': fields.one2many('survey.user_input_line',
'user_input_id', 'Answers'),
'user_input_id', 'Answers'),
}
_defaults = {
'date_create': fields.datetime.now,
@ -649,13 +625,48 @@ class survey_user_input(osv.osv):
# raise osv.except_osv(_('Warning!'), _('You must enter one or more answers for question "%s" of page %s .') % (vals['question'], page.title))
def do_clean_emptys(self, cr, uid, automatic=False, context=None):
''' Remove empty user inputs that have been created manually '''
empty_user_input_ids = self.search(cr, uid,
[('type', '=', 'manually'), ('state', '=', 'new')], context=context)
empty_user_input_ids = self.search(cr, uid, [('type', '=', 'manually'),
('state', '=', 'new')],
context=context)
if empty_user_input_ids:
self.unlink(cr, uid, empty_user_input_ids, context=context)
self.unlink(cr, uid, empty_user_input_ids, context=context)
def save_lines(self, cr, uid, user_input_id, question, post, answer_tag,
context=None):
try:
saver = getattr(self, 'save_' + question.type)
except AttributeError:
_logger.error(question.type + ": This type of question has no saving function")
return False
else:
return saver(cr, uid, user_input_id, question, post, answer_tag, context=context)
# i f of question type select right saving meth
# user_input_obj.write(cr, uid, [user_input_id], {'state': 'skip'}, context=context)
# vals = {
# 'user_input_id': user_input_id,
# 'question_id': question.id,
# 'page_id': page_id,
# 'survey_id': survey.id,
# }
# if answer_tag in post:
# user_input_obj.save_lines(cr,uid,context=context)
# if question.type == 'textbox':
# vals.update({'answer_type': 'text', 'value_text': post[answer_tag]})
# pass
# else:
# vals.update({'skipped': True})
# user_input_line_obj.create(cr, uid, vals, context=context)
#here store answers
# def save_textbox(self, cr, uid, user_input_id, question, post, answer_tag, context=None):
# return True
def action_survey_resent(self, cr, uid, ids, context=None):
record = self.browse(cr, uid, ids[0], context=context)
@ -712,17 +723,6 @@ class survey_user_input(osv.osv):
'context': context
}
def name_get(self, cr, uid, ids, context=None):
if not len(ids):
return []
reads = self.read(cr, uid, ids, ['partner_id', 'date_create'],
context=context)
res = []
for record in reads:
name = (record['partner_id'] and record['partner_id'][1] or '') + ' (' + record['date_create'].split('.')[0] + ')'
res.append((record['id'], name))
return res
def copy(self, cr, uid, id, default=None, context=None):
raise osv.except_osv(_('Warning!'), _('You cannot duplicate this \
element!'))
@ -734,21 +734,22 @@ class survey_user_input_line(osv.osv):
_rec_name = 'date_create'
_columns = {
'user_input_id': fields.many2one('survey.user_input', 'User Input',
ondelete='cascade', required=1),
ondelete='cascade', required=1),
'question_id': fields.many2one('survey.question', 'Question',
ondelete='restrict'),
ondelete='restrict'),
'page_id': fields.related('question_id', 'page_id', type='many2one',
relation='survey.page', string="Page"),
relation='survey.page', string="Page"),
'survey_id': fields.related('user_input_id', 'survey_id',
type="many2one", relation="survey.survey", string='Survey'),
type="many2one", relation="survey.survey",
string='Survey'),
'date_create': fields.datetime('Create Date', required=1), # drop
'skipped': fields.boolean('Skipped'),
'answer_type': fields.selection([('text', 'Text'),
('number', 'Number'),
('date', 'Date'),
('free_text', 'Free Text'),
('suggestion', 'Suggestion')],
'Answer Type'),
('number', 'Number'),
('date', 'Date'),
('free_text', 'Free Text'),
('suggestion', 'Suggestion')],
'Answer Type'),
'value_text': fields.char("Text answer"),
'value_number': fields.float("Numerical answer"),
'value_date': fields.datetime("Date answer"),
@ -760,4 +761,12 @@ class survey_user_input_line(osv.osv):
'date_create': fields.datetime.now
}
def dict_keys_startswith(self, dictionary, string):
'''Returns a dictionary containing the elements of <dict> whose keys start
with <string>.
.. note::
This function uses dictionary comprehensions (Python >= 2.7)'''
return {k: dictionary[k] for k in filter(lambda key: key.startswith(string), dictionary.keys())}
# vim: exp and tab: smartindent: tabstop=4: softtabstop=4: shiftwidth=4:

View File

@ -22,7 +22,7 @@
from openerp.osv.orm import except_orm
from openerp.tools import mute_logger
from time import time
w
class test_survey_answer():
@ -115,3 +115,5 @@ class test_survey_answer():
# self.assertEqual(self.survey_browse.state, 'close', 'Survey should be in cancel state')
# # sur_question = self.on_change_type(cr, uid, [ref("survey_Initial_partner_feedback")], 'multiple_textboxes_diff_type')
# vim: exp and tab: smartindent: tabstop=4: softtabstop=4: shiftwidth=4:

View File

@ -242,8 +242,6 @@
<field name="public_url"/>
<templates>
<div t-name="kanban-box" t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_survey oe_kanban_global_click">
<span class="oe_survey_fill">
</span>
<div class="oe_dropdown_toggle oe_dropdown_kanban" t-if="widget.view.is_action_enabled('edit')">
<span class="oe_e">i</span>
<ul class="oe_dropdown_menu">
@ -262,11 +260,17 @@
<a t-if="record.state.raw_value === 'draft'" title="Draft" class="oe_kanban_status"> </a>
<a t-if="record.state.raw_value === 'open'" title="Open" class="oe_kanban_status_green"> </a>
<a t-if="record.state.raw_value === 'close'" title="Closed" class="oe_kanban_status_red"> </a>
<a t-if="record.state.raw_value === 'cancel'" title="Cancelled" class="oe_kanban_status_salmon"> </a>
</span>
<h3 class="oe_kanban_ellipsis"><t t-esc="record.title.raw_value.toString()"></t></h3>
<div>tot started surveys</div>
<div>tot sent surveys</div>
<div>tot completed surveys</div>
<div><p>
<ul>
<li>Opening: <field name="date_open"/></li>
<li>Closing: <field name="date_close"/></li>
</ul>
</p></div>
<div class="oe_stats_box"><span><field name="tot_start_survey"/></span><br/>started</div>
<div class="oe_stats_box"><span><field name="tot_comp_survey"/></span><br/>completed</div>
</div>
</div>
</templates>
@ -395,26 +399,16 @@
</group>
<!-- Labels -->
<group colspan="4" nolabel="1" attrs="{'invisible':[('type','not in',['simple_choice', 'multiple_choice'])]}">
<group colspan="4" nolabel="1" attrs="{'invisible':[('type','not in',['simple_choice', 'multiple_choice', 'matrix'])]}">
<field name="display_mode" string="Display mode" attrs="{'invisible':[('type','not in',['simple_choice'])]}"/>
<field name="column_nb" string="Number of columns" attrs="{'invisible':[('display_mode','=','dropdown'), ('type','=','simple_choice')]}"/>
<field name="labels_ids" colspan="4" nolabel="1" context="{'default_question_id': active_id}">
<tree string="Answer choices" editable="bottom">
<field name="sequence" widget="handle"/>
<field name="value" />
</tree>
</field>
</group>
<!-- Sub-questions -->
<group colspan="4" attrs="{'invisible':[('type','not in',['matrix'])]}">
<field name="labels_ids" colspan="4" nolabel="1" context="{'default_question_id': active_id}">
<tree editable="bottom">
<field name="sequence" widget="handle"/>
<field name="value" string="Columns labels"/>
<field name="value" string="Answer choices"/>
</tree>
</field>
<field name="labels_ids_2" colspan="4" nolabel="1" context="{'default_question_id_2': active_id}">
<field name="labels_ids_2" colspan="4" nolabel="1" context="{'default_question_id_2': active_id}" attrs="{'invisible':[('type','not in',['matrix'])]}">
<tree editable="bottom">
<field name="sequence" widget="handle"/>
<field name="value" string="Rows labels"/>

View File

@ -19,11 +19,12 @@
#
##############################################################################
import re
from openerp.osv import osv
from openerp.osv import fields
from datetime import datetime
from openerp.tools.translate import _
from datetime import datetime
import re
import uuid
emails_split = re.compile(r"[;,\n\r]+")

View File

@ -22,6 +22,7 @@
from openerp.osv import fields, osv
from openerp.tools.translate import _
class survey_print_statistics(osv.osv_memory):
_name = 'survey.print.statistics'
_columns = {