2013-11-05 10:36:54 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
##############################################################################
|
|
|
|
#
|
|
|
|
# OpenERP, Open Source Management Solution
|
|
|
|
# Copyright (C) 2013-Today OpenERP SA (<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/>.
|
|
|
|
#
|
|
|
|
##############################################################################
|
|
|
|
|
|
|
|
from openerp.addons.web import http
|
|
|
|
from openerp.addons.web.http import request
|
|
|
|
from openerp.addons.website.models import website
|
2013-11-20 15:13:01 +00:00
|
|
|
from openerp import SUPERUSER_ID
|
2013-11-05 10:36:54 +00:00
|
|
|
|
2013-11-08 07:53:47 +00:00
|
|
|
import werkzeug
|
2013-11-15 15:14:35 +00:00
|
|
|
import json
|
2013-11-08 07:53:47 +00:00
|
|
|
import logging
|
2013-11-15 15:14:35 +00:00
|
|
|
import re
|
2013-11-08 07:53:47 +00:00
|
|
|
|
|
|
|
_logger = logging.getLogger(__name__)
|
2013-11-05 10:36:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
class WebsiteSurvey(http.Controller):
|
|
|
|
|
2013-11-15 07:51:50 +00:00
|
|
|
# Survey list
|
2013-11-05 10:36:54 +00:00
|
|
|
@website.route(['/survey/',
|
2013-11-29 08:49:14 +00:00
|
|
|
'/survey/list/'],
|
|
|
|
type='http', auth='public', multilang=True)
|
2013-11-06 15:24:06 +00:00
|
|
|
def list_surveys(self, **post):
|
2013-11-08 07:53:47 +00:00
|
|
|
'''Lists all the public surveys'''
|
2013-11-05 10:36:54 +00:00
|
|
|
cr, uid, context = request.cr, request.uid, request.context
|
|
|
|
survey_obj = request.registry['survey.survey']
|
2013-11-08 07:53:47 +00:00
|
|
|
survey_ids = survey_obj.search(cr, uid, [('state', '=', 'open'),
|
2013-11-29 08:49:14 +00:00
|
|
|
('page_ids', '!=', 'None')],
|
|
|
|
context=context)
|
2013-11-05 10:36:54 +00:00
|
|
|
surveys = survey_obj.browse(cr, uid, survey_ids, context=context)
|
2013-11-05 15:28:21 +00:00
|
|
|
return request.website.render('survey.list', {'surveys': surveys})
|
2013-11-05 10:36:54 +00:00
|
|
|
|
2013-11-26 15:17:26 +00:00
|
|
|
# Survey start
|
|
|
|
@website.route(['/survey/start/<model("survey.survey"):survey>',
|
|
|
|
'/survey/start/<model("survey.survey"):survey>/<string:token>'],
|
2013-11-29 08:49:14 +00:00
|
|
|
type='http', auth='public', multilang=True)
|
2013-11-26 15:17:26 +00:00
|
|
|
def start_survey(self, survey, token=None, **post):
|
|
|
|
cr, uid, context = request.cr, request.uid, request.context
|
|
|
|
survey_obj = request.registry['survey.survey']
|
|
|
|
user_input_obj = request.registry['survey.user_input']
|
|
|
|
|
|
|
|
# In case of bad survey, redirect to surveys list
|
|
|
|
if survey_obj.exists(cr, uid, survey.id, context=context) == []:
|
|
|
|
return werkzeug.utils.redirect("/survey/")
|
|
|
|
|
|
|
|
# In case of auth required, block public user
|
|
|
|
if survey.auth_required and uid == request.registry['website'].get_public_user(request.cr, SUPERUSER_ID, request.context).id:
|
|
|
|
return request.website.render("website.401")
|
|
|
|
|
|
|
|
# In case of non open surveys
|
|
|
|
if survey.state != 'open':
|
|
|
|
return request.website.render("survey.notopen")
|
|
|
|
|
|
|
|
# If enough surveys completed
|
|
|
|
if survey.user_input_limit > 0:
|
|
|
|
completed = user_input_obj.search(cr, uid, [('state', '=', 'done')], count=True)
|
|
|
|
if completed >= survey.user_input_limit:
|
|
|
|
return request.website.render("survey.notopen")
|
|
|
|
|
|
|
|
# Manual surveying
|
|
|
|
if not token:
|
|
|
|
if survey.visible_to_user:
|
|
|
|
user_input_id = user_input_obj.create(cr, uid, {'survey_id': survey.id})
|
|
|
|
user_input = user_input_obj.browse(cr, uid, [user_input_id], context=context)[0]
|
|
|
|
else: # An user cannot open hidden surveys without token
|
|
|
|
return request.website.render("website.403")
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
user_input_id = user_input_obj.search(cr, uid, [('token', '=', token)])[0]
|
|
|
|
except IndexError: # Invalid token
|
|
|
|
return request.website.render("website.403")
|
|
|
|
else:
|
|
|
|
user_input = user_input_obj.browse(cr, uid, [user_input_id], context=context)[0]
|
|
|
|
|
|
|
|
# Prevent opening of the survey if the deadline has turned out
|
|
|
|
# ! This will NOT disallow access to users who have already partially filled the survey !
|
|
|
|
# if user_input.deadline > fields.date.now() and user_input.state == 'new':
|
|
|
|
# return request.website.render("survey.notopen")
|
|
|
|
# TODO check if this is ok
|
|
|
|
|
|
|
|
# Select the right page
|
|
|
|
|
|
|
|
if user_input.state == 'new': # Intro page
|
|
|
|
data = {'survey': survey, 'page': None, 'token': user_input.token}
|
|
|
|
return request.website.render('survey.survey_init', data)
|
|
|
|
else:
|
|
|
|
return request.redirect('/survey/fill/%s/%s' % (survey.id, user_input.token))
|
|
|
|
|
|
|
|
|
2013-11-20 15:13:01 +00:00
|
|
|
# Survey displaying
|
2013-11-25 08:04:46 +00:00
|
|
|
@website.route(['/survey/fill/<model("survey.survey"):survey>/<string:token>'],
|
2013-11-28 07:44:18 +00:00
|
|
|
type='http', auth='public', multilang=True)
|
2013-11-26 15:17:26 +00:00
|
|
|
def fill_survey(self, survey, token, **post):
|
2013-11-08 07:53:47 +00:00
|
|
|
'''Display and validates a survey'''
|
2013-11-05 15:28:21 +00:00
|
|
|
cr, uid, context = request.cr, request.uid, request.context
|
|
|
|
survey_obj = request.registry['survey.survey']
|
2013-11-20 15:13:01 +00:00
|
|
|
user_input_obj = request.registry['survey.user_input']
|
2013-11-06 07:33:53 +00:00
|
|
|
|
2013-11-25 08:04:46 +00:00
|
|
|
# Mettre methode start survey sur objet survey
|
|
|
|
|
2013-11-08 07:53:47 +00:00
|
|
|
# In case of bad survey, redirect to surveys list
|
|
|
|
if survey_obj.exists(cr, uid, survey.id, context=context) == []:
|
|
|
|
return werkzeug.utils.redirect("/survey/")
|
|
|
|
|
2013-11-20 15:13:01 +00:00
|
|
|
# In case of auth required, block public user
|
|
|
|
if survey.auth_required and uid == request.registry['website'].get_public_user(request.cr, SUPERUSER_ID, request.context).id:
|
|
|
|
return request.website.render("website.401")
|
2013-11-08 07:53:47 +00:00
|
|
|
|
2013-11-20 15:13:01 +00:00
|
|
|
# In case of non open surveys
|
|
|
|
if survey.state != 'open':
|
2013-11-25 08:04:46 +00:00
|
|
|
return request.website.render("survey.notopen")
|
2013-11-20 15:13:01 +00:00
|
|
|
|
|
|
|
# If enough surveys completed
|
|
|
|
if survey.user_input_limit > 0:
|
2013-11-20 16:15:04 +00:00
|
|
|
completed = user_input_obj.search(cr, uid, [('state', '=', 'done')], count=True)
|
2013-11-20 15:13:01 +00:00
|
|
|
if completed >= survey.user_input_limit:
|
|
|
|
return request.website.render("survey.notopen")
|
|
|
|
|
|
|
|
# Manual surveying
|
|
|
|
if not token:
|
|
|
|
if survey.visible_to_user:
|
|
|
|
user_input_id = user_input_obj.create(cr, uid, {'survey_id': survey.id})
|
|
|
|
user_input = user_input_obj.browse(cr, uid, [user_input_id], context=context)[0]
|
|
|
|
else: # An user cannot open hidden surveys without token
|
|
|
|
return request.website.render("website.403")
|
2013-11-20 16:15:04 +00:00
|
|
|
else:
|
2013-11-21 11:04:57 +00:00
|
|
|
try:
|
|
|
|
user_input_id = user_input_obj.search(cr, uid, [('token', '=', token)])[0]
|
|
|
|
except IndexError: # Invalid token
|
|
|
|
return request.website.render("website.403")
|
|
|
|
else:
|
|
|
|
user_input = user_input_obj.browse(cr, uid, [user_input_id], context=context)[0]
|
2013-11-20 15:13:01 +00:00
|
|
|
|
2013-11-25 08:04:46 +00:00
|
|
|
# Prevent opening of the survey if the deadline has turned out
|
|
|
|
# ! This will NOT disallow access to users who have already partially filled the survey !
|
|
|
|
# if user_input.deadline > fields.date.now() and user_input.state == 'new':
|
|
|
|
# return request.website.render("survey.notopen")
|
|
|
|
# TODO check if this is ok
|
2013-11-08 07:53:47 +00:00
|
|
|
|
2013-11-25 08:04:46 +00:00
|
|
|
# Select the right page
|
|
|
|
|
|
|
|
# if user_input.state == 'new' and not post: # Intro page
|
|
|
|
# data = {'survey': survey, 'page': None, 'token': user_input.token}
|
|
|
|
# return request.website.render('survey.survey', data)
|
|
|
|
if user_input.state == 'new': # First page
|
|
|
|
page, page_nr, last = self.find_next_page(survey, user_input)
|
|
|
|
data = {'survey': survey, 'page': page, 'page_nr': page_nr, 'token': user_input.token}
|
|
|
|
if last:
|
|
|
|
data.update({'last': True})
|
|
|
|
return request.website.render('survey.survey', data)
|
|
|
|
elif user_input.state == 'done': # Display success message
|
2013-11-15 07:51:50 +00:00
|
|
|
return request.website.render('survey.finished', {'survey': survey})
|
2013-11-25 08:04:46 +00:00
|
|
|
elif user_input.state == 'skip':
|
|
|
|
page, page_nr, last = self.find_next_page(survey, user_input)
|
2013-11-28 07:44:18 +00:00
|
|
|
data = {'survey': survey, 'page': page, 'page_nr': page_nr, 'token': user_input.token}
|
2013-11-25 08:04:46 +00:00
|
|
|
if last:
|
|
|
|
data.update({'last': True})
|
|
|
|
else:
|
|
|
|
return request.website.render("website.403")
|
2013-11-06 16:11:17 +00:00
|
|
|
|
2013-11-15 07:51:50 +00:00
|
|
|
# @website.route(['/survey/prefill/<model("survey.survey"):survey>'], type='json', auth='public', multilang=True):
|
2013-11-14 07:45:55 +00:00
|
|
|
|
2013-11-15 07:51:50 +00:00
|
|
|
# @website.route(['/survey/validate/<model("survey.survey"):survey>'],
|
2013-11-28 07:44:18 +00:00
|
|
|
# type='http', auth='public', multilang=True)
|
|
|
|
# def validate(self, survey, **post):
|
|
|
|
# _logger.debug('Incoming data: %s', post)
|
|
|
|
# page_id = int(post['page_id'])
|
|
|
|
# cr, uid, context = request.cr, request.uid, request.context
|
|
|
|
# questions_obj = request.registry['survey.question']
|
|
|
|
# questions_ids = questions_obj.search(cr, uid, [('page_id', '=', page_id)], context=context)
|
|
|
|
# questions = questions_obj.browse(cr, uid, questions_ids, context=context)
|
|
|
|
# errors = {}
|
|
|
|
# for question in questions:
|
|
|
|
# answer_tag = "%s_%s_%s" % (survey.id, page_id, question.id)
|
|
|
|
# errors.update(self.validate_question(question, post, answer_tag))
|
|
|
|
# ret = {}
|
|
|
|
# if (len(errors) != 0):
|
|
|
|
# ret['errors'] = errors
|
|
|
|
# return json.dumps(ret)
|
2013-11-14 07:45:55 +00:00
|
|
|
|
2013-11-15 07:51:50 +00:00
|
|
|
@website.route(['/survey/submit/<model("survey.survey"):survey>'],
|
2013-11-28 07:44:18 +00:00
|
|
|
type='http', auth='public', multilang=True)
|
2013-11-15 15:14:35 +00:00
|
|
|
def submit(self, survey, **post):
|
2013-11-20 15:13:01 +00:00
|
|
|
_logger.debug('Incoming data: %s', post)
|
2013-11-25 08:04:46 +00:00
|
|
|
page_id = int(post['page_id'])
|
|
|
|
cr, uid, context = request.cr, request.uid, request.context
|
|
|
|
questions_obj = request.registry['survey.question']
|
2013-11-28 07:44:18 +00:00
|
|
|
questions_ids = questions_obj.search(cr, uid, [('page_id', '=', page_id)], context=context)
|
2013-11-25 08:04:46 +00:00
|
|
|
questions = questions_obj.browse(cr, uid, questions_ids, context=context)
|
2013-11-14 07:45:55 +00:00
|
|
|
|
2013-11-28 07:44:18 +00:00
|
|
|
# Answer validation
|
2013-11-15 15:14:35 +00:00
|
|
|
errors = {}
|
|
|
|
for question in questions:
|
2013-11-25 08:04:46 +00:00
|
|
|
answer_tag = "%s_%s_%s" % (survey.id, page_id, question.id)
|
|
|
|
errors.update(self.validate_question(question, post, answer_tag))
|
2013-11-14 07:45:55 +00:00
|
|
|
|
2013-11-15 15:14:35 +00:00
|
|
|
ret = {}
|
|
|
|
if (len(errors) != 0):
|
2013-11-28 07:44:18 +00:00
|
|
|
# Return errors messages to webpage
|
2013-11-15 15:14:35 +00:00
|
|
|
ret['errors'] = errors
|
|
|
|
else:
|
2013-11-28 07:44:18 +00:00
|
|
|
# Store answers into database
|
2013-11-25 08:04:46 +00:00
|
|
|
user_input_obj = request.registry['survey.user_input']
|
|
|
|
try:
|
2013-11-28 07:44:18 +00:00
|
|
|
user_input_id = user_input_obj.search(cr, uid, [('token', '=', post['token'])], context=context)[0]
|
2013-11-26 15:17:26 +00:00
|
|
|
except KeyError: # Invalid token
|
2013-11-25 08:04:46 +00:00
|
|
|
return request.website.render("website.403")
|
2013-11-28 07:44:18 +00:00
|
|
|
for question in questions:
|
|
|
|
answer_tag = "%s_%s_%s" % (survey.id, page_id, question.id)
|
2013-11-29 08:49:14 +00:00
|
|
|
user_input_obj.save_lines(cr, uid, user_input_id, question, post, answer_tag, context=context)
|
2013-11-26 15:17:26 +00:00
|
|
|
ret['redirect'] = '/survey/fill/%s/%s' % (survey.id, post['token'])
|
2013-11-15 15:14:35 +00:00
|
|
|
return json.dumps(ret)
|
2013-11-15 07:51:50 +00:00
|
|
|
|
|
|
|
# Printing routes
|
2013-11-08 14:24:06 +00:00
|
|
|
@website.route(['/survey/print/<model("survey.survey"):survey>/'],
|
2013-11-28 07:44:18 +00:00
|
|
|
type='http', auth='user', multilang=True)
|
2013-11-08 14:24:06 +00:00
|
|
|
def print_empty_survey(self, survey=None, **post):
|
2013-11-08 07:53:47 +00:00
|
|
|
'''Display an empty survey in printable view'''
|
2013-11-06 16:11:17 +00:00
|
|
|
return request.website.render('survey.survey_print',
|
2013-11-28 07:44:18 +00:00
|
|
|
{'survey': survey, 'page_nr': 0})
|
2013-11-15 15:14:35 +00:00
|
|
|
|
2013-11-25 08:04:46 +00:00
|
|
|
# Pagination
|
|
|
|
|
|
|
|
def find_next_page(self, survey, user_input):
|
|
|
|
''' Find the browse record of the first unfilled page '''
|
|
|
|
if not user_input.user_input_line_ids:
|
|
|
|
return survey.page_ids[0], 0, len(survey.page_ids) == 1
|
|
|
|
else:
|
|
|
|
filled_pages = set()
|
|
|
|
for user_input_line in user_input.user_input_line_ids:
|
|
|
|
filled_pages.add(user_input_line.page_id)
|
|
|
|
last = False
|
|
|
|
page_nr = 0
|
|
|
|
nextpage = None
|
2013-11-28 07:44:18 +00:00
|
|
|
for page in survey.page_ids:
|
2013-11-25 08:04:46 +00:00
|
|
|
if page in filled_pages:
|
|
|
|
page_nr = page_nr + 1
|
|
|
|
else:
|
|
|
|
nextpage = page
|
2013-11-28 07:44:18 +00:00
|
|
|
if page_nr == len(survey.page_ids):
|
2013-11-25 08:04:46 +00:00
|
|
|
last = True
|
|
|
|
return nextpage, page_nr, last
|
|
|
|
|
2013-11-15 15:14:35 +00:00
|
|
|
# Validation methods
|
|
|
|
|
2013-11-25 08:04:46 +00:00
|
|
|
def validate_question(self, question, post, answer_tag):
|
2013-11-15 15:14:35 +00:00
|
|
|
''' Routing to the right question valider, depending on question type '''
|
|
|
|
try:
|
|
|
|
checker = getattr(self, 'validate_' + question.type)
|
|
|
|
except AttributeError:
|
2013-11-29 08:49:14 +00:00
|
|
|
_logger.error(question.type + ": This type of question has no validation method")
|
2013-11-15 15:14:35 +00:00
|
|
|
return {}
|
|
|
|
else:
|
2013-11-25 08:04:46 +00:00
|
|
|
return checker(question, post, answer_tag)
|
2013-11-15 15:14:35 +00:00
|
|
|
|
2013-11-25 08:04:46 +00:00
|
|
|
def validate_free_text(self, question, post, answer_tag):
|
2013-11-15 15:14:35 +00:00
|
|
|
errors = {}
|
|
|
|
answer = post[answer_tag].strip()
|
|
|
|
# Empty answer to mandatory question
|
|
|
|
if question.constr_mandatory and not answer:
|
|
|
|
errors.update({answer_tag: question.constr_error_msg})
|
|
|
|
return errors
|
|
|
|
|
2013-11-25 08:04:46 +00:00
|
|
|
def validate_textbox(self, question, post, answer_tag):
|
2013-11-15 15:14:35 +00:00
|
|
|
errors = {}
|
|
|
|
answer = post[answer_tag].strip()
|
|
|
|
# Empty answer to mandatory question
|
|
|
|
if question.constr_mandatory and not answer:
|
|
|
|
errors.update({answer_tag: question.constr_error_msg})
|
|
|
|
# Answer validation (if properly defined)
|
|
|
|
if answer and question.validation_required and question.validation_type:
|
|
|
|
# Length of the answer must be in a range
|
|
|
|
if question.validation_type == "has_length":
|
|
|
|
if not (question.validation_length_min <= len(answer) <= question.validation_length_max):
|
|
|
|
errors.update({answer_tag: question.validation_error_msg})
|
|
|
|
|
|
|
|
# Answer must be an integer in a particular range
|
|
|
|
elif question.validation_type == "is_integer":
|
|
|
|
try:
|
|
|
|
intanswer = int(answer)
|
|
|
|
# Answer is not an integer
|
|
|
|
except ValueError:
|
|
|
|
errors.update({answer_tag: question.validation_error_msg})
|
|
|
|
else:
|
|
|
|
# Answer is not in the right range
|
|
|
|
if not (question.validation_min_int_value <= intanswer <= question.validation_max_int_value):
|
|
|
|
errors.update({answer_tag: question.validation_error_msg})
|
|
|
|
# Answer must be a float in a particular range
|
|
|
|
elif question.validation_type == "is_decimal":
|
|
|
|
try:
|
|
|
|
floatanswer = float(answer)
|
|
|
|
# Answer is not an integer
|
|
|
|
except ValueError:
|
|
|
|
errors.update({answer_tag: question.validation_error_msg})
|
|
|
|
else:
|
|
|
|
# Answer is not in the right range
|
|
|
|
if not (question.validation_min_float_value <= floatanswer <= question.validation_max_float_value):
|
|
|
|
errors.update({answer_tag: question.validation_error_msg})
|
|
|
|
|
|
|
|
# Answer must be a date in a particular range
|
|
|
|
elif question.validation_type == "is_date":
|
|
|
|
raise Exception("Not implemented")
|
|
|
|
# Answer must be an email address
|
|
|
|
# Note: this validation is very basic:
|
|
|
|
# all the strings of the form
|
|
|
|
# <something>@<anything>.<extension>
|
|
|
|
# will be accepted
|
|
|
|
elif question.validation_type == "is_email":
|
|
|
|
if not re.match(r"[^@]+@[^@]+\.[^@]+", answer):
|
|
|
|
errors.update({answer_tag: question.validation_error_msg})
|
|
|
|
else:
|
|
|
|
pass
|
|
|
|
return errors
|
|
|
|
|
2013-11-25 08:04:46 +00:00
|
|
|
def validate_numerical_box(self, question, post, answer_tag):
|
2013-11-15 15:14:35 +00:00
|
|
|
errors = {}
|
|
|
|
answer = post[answer_tag].strip()
|
|
|
|
# Empty answer to mandatory question
|
|
|
|
if question.constr_mandatory and not answer:
|
|
|
|
errors.update({answer_tag: question.constr_error_msg})
|
|
|
|
# Checks if user input is a number
|
|
|
|
if answer:
|
|
|
|
try:
|
|
|
|
float(answer)
|
|
|
|
except ValueError:
|
|
|
|
errors.update({answer_tag: question.constr_error_msg})
|
|
|
|
return errors
|
|
|
|
|
2013-11-25 08:04:46 +00:00
|
|
|
def validate_datetime(self, question, post, answer_tag):
|
2013-11-15 15:14:35 +00:00
|
|
|
errors = {}
|
|
|
|
answer = post[answer_tag].strip()
|
|
|
|
# Empty answer to mandatory question
|
|
|
|
if question.constr_mandatory and not answer:
|
|
|
|
errors.update({answer_tag: question.constr_error_msg})
|
|
|
|
# Checks if user input is a datetime
|
|
|
|
# TODO when datepicker will be available
|
|
|
|
return errors
|
|
|
|
|
2013-11-26 12:53:03 +00:00
|
|
|
def validate_simple_choice(self, question, post, answer_tag):
|
|
|
|
errors = {}
|
2013-11-26 15:17:26 +00:00
|
|
|
if question.comments_allowed:
|
|
|
|
comment_tag = "%s_%s" % (answer_tag, question.comment_children_ids[0].id)
|
2013-11-26 12:53:03 +00:00
|
|
|
# Empty answer to mandatory question
|
|
|
|
if question.constr_mandatory and not answer_tag in post:
|
|
|
|
errors.update({answer_tag: question.constr_error_msg})
|
2013-11-26 15:17:26 +00:00
|
|
|
if question.constr_mandatory and answer_tag in post and post[answer_tag].strip() == '':
|
|
|
|
errors.update({answer_tag: question.constr_error_msg})
|
2013-11-26 12:53:03 +00:00
|
|
|
# Answer is a comment and is empty
|
|
|
|
if question.constr_mandatory and answer_tag in post and post[answer_tag] == "-1" and question.comment_count_as_answer and comment_tag in post and not post[comment_tag].strip():
|
|
|
|
errors.update({answer_tag: question.constr_error_msg})
|
|
|
|
# There is a comment and it should be validated
|
|
|
|
# if question.comment_allowed and comment_tag in post and post[comment_tag].strip():
|
|
|
|
|
|
|
|
### if comments_allowed:
|
|
|
|
### if validation des comments required
|
|
|
|
###
|
|
|
|
### if comment_count_as answer and question mandatory
|
|
|
|
###
|
|
|
|
### else:
|
|
|
|
### if question mandatory:
|
|
|
|
|
|
|
|
return errors
|
2013-11-15 15:14:35 +00:00
|
|
|
|
2013-11-25 08:04:46 +00:00
|
|
|
# def validate_multiple_choice(self, question, post, answer_tag):
|
2013-11-15 15:14:35 +00:00
|
|
|
# problems = []
|
|
|
|
# return problems
|
|
|
|
|
2013-11-25 08:04:46 +00:00
|
|
|
# def validate_matrix(self, question, post, answer_tag):
|
2013-11-15 15:14:35 +00:00
|
|
|
# problems = []
|
|
|
|
# return problems
|
|
|
|
|
2013-11-29 08:49:14 +00:00
|
|
|
# vim: exp and tab: smartindent: tabstop=4: softtabstop=4: shiftwidth=4:
|