diff --git a/addons/calendar/__openerp__.py b/addons/calendar/__openerp__.py
index 2f06a0b5cb9..f0417db1bf6 100644
--- a/addons/calendar/__openerp__.py
+++ b/addons/calendar/__openerp__.py
@@ -40,7 +40,6 @@ If you need to manage your meetings, you should install the CRM module.
'website': 'http://www.openerp.com',
'demo': ['calendar_demo.xml'],
'data': [
- 'security/calendar_security.xml',
'security/ir.model.access.csv',
'calendar_view.xml',
'contacts_view.xml',
diff --git a/addons/calendar/security/calendar_security.xml b/addons/calendar/security/calendar_security.xml
deleted file mode 100644
index 7c4363d21fc..00000000000
--- a/addons/calendar/security/calendar_security.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
- Survey / User
-
-
-
-
diff --git a/addons/calendar/security/ir.model.access.csv b/addons/calendar/security/ir.model.access.csv
index caa7f0c6970..4da2e1a1cc6 100644
--- a/addons/calendar/security/ir.model.access.csv
+++ b/addons/calendar/security/ir.model.access.csv
@@ -1,7 +1,6 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_calendar_attendee,calendar.attendee,model_calendar_attendee,,1,1,1,1
access_calendar_alarm,calendar.alarm,model_calendar_alarm,base.group_user,1,1,1,1
-access_calendar_attendee_survey_user,calendar.attendee,model_calendar_attendee,base.group_survey_user,1,0,0,0
access_calendar_event_manager,calendar.event.manager,model_calendar_event,base.group_sale_manager,1,1,1,1
access_calendar_event,calendar.event,model_calendar_event,base.group_sale_salesman,1,1,1,0
access_calendar_event_all,calendar.event_all,model_calendar_event,base.group_user,1,1,1,1
diff --git a/addons/hr_evaluation/__openerp__.py b/addons/hr_evaluation/__openerp__.py
index 711571a2e89..2d62465ecb5 100644
--- a/addons/hr_evaluation/__openerp__.py
+++ b/addons/hr_evaluation/__openerp__.py
@@ -20,22 +20,24 @@
##############################################################################
{
- 'name' : 'Employee Appraisals',
+ 'name': 'Employee Appraisals',
'version': '0.1',
'author': 'OpenERP SA',
'category': 'Human Resources',
'sequence': 31,
'website': 'http://www.openerp.com',
'summary': 'Periodical Evaluations, Appraisals, Surveys',
- 'images': ['images/hr_evaluation_analysis.jpeg','images/hr_evaluation.jpeg','images/hr_interview_requests.jpeg'],
- 'depends': ['hr','calendar','survey'],
+ 'images': ['images/hr_evaluation_analysis.jpeg',
+ 'images/hr_evaluation.jpeg',
+ 'images/hr_interview_requests.jpeg'],
+ 'depends': ['hr', 'calendar', 'survey'],
'description': """
Periodical Employees evaluation and appraisals
==============================================
-By using this application you can maintain the motivational process by doing periodical evaluations of your employees' performance. The regular assessment of human resources can benefit your people as well your organization.
+By using this application you can maintain the motivational process by doing periodical evaluations of your employees' performance. The regular assessment of human resources can benefit your people as well your organization.
-An evaluation plan can be assigned to each employee. These plans define the frequency and the way you manage your periodic personal evaluations. You will be able to define steps and attach interview forms to each step.
+An evaluation plan can be assigned to each employee. These plans define the frequency and the way you manage your periodic personal evaluations. You will be able to define steps and attach interview forms to each step.
Manages several types of evaluations: bottom-up, top-down, self-evaluations and the final evaluation by the manager.
@@ -47,23 +49,22 @@ Key Features
* Every evaluation filled by employees can be viewed in a PDF form.
* Interview Requests are generated automatically by OpenERP according to employees evaluation plans. Each user receives automatic emails and requests to perform a periodical evaluation of their colleagues.
""",
- "demo": ["hr_evaluation_demo.xml"],
"data": [
'security/ir.model.access.csv',
'security/hr_evaluation_security.xml',
'hr_evaluation_view.xml',
'report/hr_evaluation_report_view.xml',
'board_hr_evaluation_view.xml',
+ 'survey_data_appraisal.xml',
'hr_evaluation_data.xml',
'hr_evaluation_installer.xml',
],
- 'test': [
- 'test/test_hr_evaluation.yml',
- 'test/hr_evalution_demo.yml',
- ],
+ "demo": ["hr_evaluation_demo.xml"],
+ # 'test': [
+ # 'test/test_hr_evaluation.yml',
+ # 'test/hr_evalution_demo.yml',
+ # ],
'auto_install': False,
'installable': True,
'application': True,
}
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/hr_evaluation/hr_evaluation.py b/addons/hr_evaluation/hr_evaluation.py
index 462154e9e4a..7d9f45f3585 100644
--- a/addons/hr_evaluation/hr_evaluation.py
+++ b/addons/hr_evaluation/hr_evaluation.py
@@ -19,15 +19,17 @@
#
##############################################################################
-from datetime import datetime
+from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from dateutil import parser
import time
from openerp.osv import fields, osv
from openerp.tools.translate import _
+from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT as DF
-class hr_evaluation_plan(osv.osv):
+
+class hr_evaluation_plan(osv.Model):
_name = "hr_evaluation.plan"
_description = "Appraisal Plan"
_columns = {
@@ -42,11 +44,11 @@ class hr_evaluation_plan(osv.osv):
'active': True,
'month_first': 6,
'month_next': 12,
- 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c),
+ 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c),
}
-class hr_evaluation_plan_phase(osv.osv):
+class hr_evaluation_plan_phase(osv.Model):
_name = "hr_evaluation.plan.phase"
_description = "Appraisal Plan Phase"
_order = "sequence"
@@ -54,13 +56,13 @@ class hr_evaluation_plan_phase(osv.osv):
'name': fields.char("Phase", size=64, required=True),
'sequence': fields.integer("Sequence"),
'company_id': fields.related('plan_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
- 'plan_id': fields.many2one('hr_evaluation.plan','Appraisal Plan', ondelete='cascade'),
+ 'plan_id': fields.many2one('hr_evaluation.plan', 'Appraisal Plan', ondelete='cascade'),
'action': fields.selection([
- ('top-down','Top-Down Appraisal Requests'),
- ('bottom-up','Bottom-Up Appraisal Requests'),
- ('self','Self Appraisal Requests'),
- ('final','Final Interview')], 'Action', required=True),
- 'survey_id': fields.many2one('survey','Appraisal Form',required=True),
+ ('top-down', 'Top-Down Appraisal Requests'),
+ ('bottom-up', 'Bottom-Up Appraisal Requests'),
+ ('self', 'Self Appraisal Requests'),
+ ('final', 'Final Interview')], 'Action', required=True),
+ 'survey_id': fields.many2one('survey.survey', 'Appraisal Form', required=True),
'send_answer_manager': fields.boolean('All Answers',
help="Send all answers to the manager"),
'send_answer_employee': fields.boolean('All Answers',
@@ -72,15 +74,14 @@ class hr_evaluation_plan_phase(osv.osv):
'wait': fields.boolean('Wait Previous Phases',
help="Check this box if you want to wait that all preceding phases " +
"are finished before launching this phase."),
- 'mail_feature': fields.boolean('Send mail for this phase', help="Check this box if you want to send mail to employees"+
- " coming under this phase"),
+ 'mail_feature': fields.boolean('Send mail for this phase', help="Check this box if you want to send mail to employees coming under this phase"),
'mail_body': fields.text('Email'),
- 'email_subject':fields.text('char')
+ 'email_subject': fields.text('Subject')
}
_defaults = {
'sequence': 1,
'email_subject': _('''Regarding '''),
- 'mail_body': lambda *a:_('''
+ 'mail_body': lambda *a: _('''
Date: %(date)s
Dear %(employee_name)s,
@@ -98,26 +99,24 @@ Thanks,
}
-class hr_employee(osv.osv):
+class hr_employee(osv.Model):
_name = "hr.employee"
- _inherit="hr.employee"
-
+ _inherit = "hr.employee"
_columns = {
'evaluation_plan_id': fields.many2one('hr_evaluation.plan', 'Appraisal Plan'),
'evaluation_date': fields.date('Next Appraisal Date', help="The date of the next appraisal is computed by the appraisal plan's dates (first appraisal + periodicity)."),
}
- def run_employee_evaluation(self, cr, uid, automatic=False, use_new_cursor=False, context=None):
+
+ def run_employee_evaluation(self, cr, uid, automatic=False, use_new_cursor=False, context=None): # cronjob
now = parser.parse(datetime.now().strftime('%Y-%m-%d'))
obj_evaluation = self.pool.get('hr_evaluation.evaluation')
- emp_ids =self.search(cr, uid, [ ('evaluation_plan_id','<>',False), ('evaluation_date','=', False)], context=context)
+ emp_ids = self.search(cr, uid, [('evaluation_plan_id', '<>', False), ('evaluation_date', '=', False)], context=context)
for emp in self.browse(cr, uid, emp_ids, context=context):
- first_date = (now+ relativedelta(months=emp.evaluation_plan_id.month_first)).strftime('%Y-%m-%d')
+ first_date = (now + relativedelta(months=emp.evaluation_plan_id.month_first)).strftime('%Y-%m-%d')
self.write(cr, uid, [emp.id], {'evaluation_date': first_date}, context=context)
- emp_ids =self.search(cr, uid, [
- ('evaluation_plan_id','<>',False), ('evaluation_date','<=', time.strftime("%Y-%m-%d")),
- ], context=context)
+ emp_ids = self.search(cr, uid, [('evaluation_plan_id', '<>', False), ('evaluation_date', '<=', time.strftime("%Y-%m-%d"))], context=context)
for emp in self.browse(cr, uid, emp_ids, context=context):
next_date = (now + relativedelta(months=emp.evaluation_plan_id.month_next)).strftime('%Y-%m-%d')
self.write(cr, uid, [emp.id], {'evaluation_date': next_date}, context=context)
@@ -126,39 +125,35 @@ class hr_employee(osv.osv):
return True
-
-class hr_evaluation(osv.osv):
+class hr_evaluation(osv.Model):
_name = "hr_evaluation.evaluation"
_inherit = "mail.thread"
_description = "Employee Appraisal"
- _rec_name = 'employee_id'
_columns = {
'date': fields.date("Appraisal Deadline", required=True, select=True),
'employee_id': fields.many2one('hr.employee', "Employee", required=True),
'note_summary': fields.text('Appraisal Summary'),
- 'note_action': fields.text('Action Plan',
- help="If the evaluation does not meet the expectations, you can propose"+
- "an action plan"),
+ 'note_action': fields.text('Action Plan', help="If the evaluation does not meet the expectations, you can propose an action plan"),
'rating': fields.selection([
- ('0','Significantly bellow expectations'),
- ('1','Did not meet expectations'),
- ('2','Meet expectations'),
- ('3','Exceeds expectations'),
- ('4','Significantly exceeds expectations'),
+ ('0', 'Significantly below expectations'),
+ ('1', 'Do not meet expectations'),
+ ('2', 'Meet expectations'),
+ ('3', 'Exceeds expectations'),
+ ('4', 'Significantly exceeds expectations'),
], "Appreciation", help="This is the appreciation on which the evaluation is summarized."),
- 'survey_request_ids': fields.one2many('hr.evaluation.interview','evaluation_id','Appraisal Forms'),
+ 'survey_request_ids': fields.one2many('hr.evaluation.interview', 'evaluation_id', 'Appraisal Forms'),
'plan_id': fields.many2one('hr_evaluation.plan', 'Plan', required=True),
'state': fields.selection([
- ('draft','New'),
- ('cancel','Cancelled'),
- ('wait','Plan In Progress'),
- ('progress','Waiting Appreciation'),
- ('done','Done'),
+ ('draft', 'New'),
+ ('cancel', 'Cancelled'),
+ ('wait', 'Plan In Progress'),
+ ('progress', 'Waiting Appreciation'),
+ ('done', 'Done'),
], 'Status', required=True, readonly=True),
'date_close': fields.date('Ending Date', select=True),
}
_defaults = {
- 'date': lambda *a: (parser.parse(datetime.now().strftime('%Y-%m-%d')) + relativedelta(months =+ 1)).strftime('%Y-%m-%d'),
+ 'date': lambda *a: (parser.parse(datetime.now().strftime('%Y-%m-%d')) + relativedelta(months=+1)).strftime('%Y-%m-%d'),
'state': lambda *a: 'draft',
}
@@ -169,7 +164,8 @@ class hr_evaluation(osv.osv):
res = []
for record in reads:
name = record.plan_id.name
- res.append((record['id'], name))
+ employee = record.employee_id.name_related
+ res.append((record['id'], name + ' / ' + employee))
return res
def onchange_employee_id(self, cr, uid, ids, employee_id, context=None):
@@ -183,7 +179,6 @@ class hr_evaluation(osv.osv):
return {'value': vals}
def button_plan_in_progress(self, cr, uid, ids, context=None):
- mail_message = self.pool.get('mail.message')
hr_eval_inter_obj = self.pool.get('hr.evaluation.interview')
if context is None:
context = {}
@@ -202,10 +197,9 @@ class hr_evaluation(osv.osv):
int_id = hr_eval_inter_obj.create(cr, uid, {
'evaluation_id': evaluation.id,
- 'survey_id': phase.survey_id.id,
- 'date_deadline': (parser.parse(datetime.now().strftime('%Y-%m-%d')) + relativedelta(months =+ 1)).strftime('%Y-%m-%d'),
+ 'phase_id': phase.id,
+ 'deadline': (parser.parse(datetime.now().strftime('%Y-%m-%d')) + relativedelta(months=+1)).strftime('%Y-%m-%d'),
'user_id': child.user_id.id,
- 'user_to_review_id': evaluation.employee_id.id
}, context=context)
if phase.wait:
wait = True
@@ -214,7 +208,7 @@ class hr_evaluation(osv.osv):
if (not wait) and phase.mail_feature:
body = phase.mail_body % {'employee_name': child.name, 'user_signature': child.user_id.signature,
- 'eval_name': phase.survey_id.title, 'date': time.strftime('%Y-%m-%d'), 'time': time }
+ 'eval_name': phase.survey_id.title, 'date': time.strftime('%Y-%m-%d'), 'time': time}
sub = phase.email_subject
if child.work_email:
vals = {'state': 'outgoing',
@@ -224,32 +218,32 @@ class hr_evaluation(osv.osv):
'email_from': evaluation.employee_id.work_email}
self.pool.get('mail.mail').create(cr, uid, vals, context=context)
- self.write(cr, uid, ids, {'state':'wait'}, context=context)
+ self.write(cr, uid, ids, {'state': 'wait'}, context=context)
return True
def button_final_validation(self, cr, uid, ids, context=None):
request_obj = self.pool.get('hr.evaluation.interview')
- self.write(cr, uid, ids, {'state':'progress'}, context=context)
+ self.write(cr, uid, ids, {'state': 'progress'}, context=context)
for evaluation in self.browse(cr, uid, ids, context=context):
if evaluation.employee_id and evaluation.employee_id.parent_id and evaluation.employee_id.parent_id.user_id:
self.message_subscribe_users(cr, uid, [evaluation.id], user_ids=[evaluation.employee_id.parent_id.user_id.id], context=context)
- if len(evaluation.survey_request_ids) != len(request_obj.search(cr, uid, [('evaluation_id', '=', evaluation.id),('state', 'in', ['done','cancel'])], context=context)):
- raise osv.except_osv(_('Warning!'),_("You cannot change state, because some appraisal(s) are in waiting answer or draft state."))
+ if len(evaluation.survey_request_ids) != len(request_obj.search(cr, uid, [('evaluation_id', '=', evaluation.id), ('state', 'in', ['done', 'cancel'])], context=context)):
+ raise osv.except_osv(_('Warning!'), _("You cannot change state, because some appraisal forms have not been completed."))
return True
def button_done(self, cr, uid, ids, context=None):
- self.write(cr, uid, ids,{'state':'done', 'date_close': time.strftime('%Y-%m-%d')}, context=context)
+ self.write(cr, uid, ids, {'state': 'done', 'date_close': time.strftime('%Y-%m-%d')}, context=context)
return True
def button_cancel(self, cr, uid, ids, context=None):
- interview_obj=self.pool.get('hr.evaluation.interview')
+ interview_obj = self.pool.get('hr.evaluation.interview')
evaluation = self.browse(cr, uid, ids[0], context)
interview_obj.survey_req_cancel(cr, uid, [r.id for r in evaluation.survey_request_ids])
- self.write(cr, uid, ids,{'state':'cancel'}, context=context)
+ self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
return True
def button_draft(self, cr, uid, ids, context=None):
- self.write(cr, uid, ids,{'state': 'draft'}, context=context)
+ self.write(cr, uid, ids, {'state': 'draft'}, context=context)
return True
def copy(self, cr, uid, id, default=None, context=None):
@@ -260,65 +254,90 @@ class hr_evaluation(osv.osv):
default = default.copy()
default['survey_request_ids'] = []
return super(hr_evaluation, self).copy(cr, uid, id, default, context=context)
-
+
def write(self, cr, uid, ids, vals, context=None):
if vals.get('employee_id'):
employee_id = self.pool.get('hr.employee').browse(cr, uid, vals.get('employee_id'), context=context)
if employee_id.parent_id and employee_id.parent_id.user_id:
vals['message_follower_ids'] = [(4, employee_id.parent_id.user_id.partner_id.id)]
if 'date' in vals:
- new_vals = {'date_deadline': vals.get('date')}
+ new_vals = {'deadline': vals.get('date')}
obj_hr_eval_iterview = self.pool.get('hr.evaluation.interview')
- for evalutation in self.browse(cr, uid, ids, context=context):
- for survey_req in evalutation.survey_request_ids:
+ for evaluation in self.browse(cr, uid, ids, context=context):
+ for survey_req in evaluation.survey_request_ids:
obj_hr_eval_iterview.write(cr, uid, [survey_req.id], new_vals, context=context)
return super(hr_evaluation, self).write(cr, uid, ids, vals, context=context)
-class survey_request(osv.osv):
- _inherit = "survey.request"
- _columns = {
- 'is_evaluation': fields.boolean('Is Appraisal?'),
- }
-
-
-class hr_evaluation_interview(osv.osv):
+class hr_evaluation_interview(osv.Model):
_name = 'hr.evaluation.interview'
- _inherits = {'survey.request': 'request_id'}
- _inherit = 'mail.thread'
- _rec_name = 'request_id'
+ _inherit = 'mail.thread'
+ _rec_name = 'user_to_review_id'
_description = 'Appraisal Interview'
_columns = {
- 'request_id': fields.many2one('survey.request','Request_id', ondelete='cascade', required=True),
- 'user_to_review_id': fields.many2one('hr.employee', 'Employee to Interview'),
- 'evaluation_id': fields.many2one('hr_evaluation.evaluation', 'Appraisal Form'),
+ 'request_id': fields.many2one('survey.user_input', 'Survey Request', ondelete='cascade', readonly=True),
+ 'evaluation_id': fields.many2one('hr_evaluation.evaluation', 'Appraisal Plan', required=True),
+ 'phase_id': fields.many2one('hr_evaluation.plan.phase', 'Appraisal Phase', required=True),
+ 'user_to_review_id': fields.related('evaluation_id', 'employee_id', type="many2one", relation="hr.employee", string="Employee to evaluate"),
+ 'user_id': fields.many2one('res.users', 'Interviewer'),
+ 'state': fields.selection([('draft', "Draft"),
+ ('waiting_answer', "In progress"),
+ ('done', "Done"),
+ ('cancel', "Cancelled")],
+ string="State", required=True),
+ 'survey_id': fields.related('phase_id', 'survey_id', string="Appraisal Form", type="many2one", relation="survey.survey"),
+ 'deadline': fields.related('request_id', 'deadline', type="datetime", string="Deadline"),
}
_defaults = {
- 'is_evaluation': True,
+ 'state': 'draft'
}
+ def create(self, cr, uid, vals, context=None):
+ phase_obj = self.pool.get('hr_evaluation.plan.phase')
+ survey_id = phase_obj.read(cr, uid, vals.get('phase_id'), fields=['survey_id'], context=context)['survey_id'][0]
+
+ if vals.get('user_id'):
+ user_obj = self.pool.get('res.users')
+ partner_id = user_obj.read(cr, uid, vals.get('user_id'), fields=['partner_id'], context=context)['partner_id'][0]
+ else:
+ partner_id = None
+
+ user_input_obj = self.pool.get('survey.user_input')
+
+ if not vals.get('deadline'):
+ vals['deadline'] = (datetime.now() + timedelta(days=28)).strftime(DF)
+
+ ret = user_input_obj.create(cr, uid, {'survey_id': survey_id,
+ 'deadline': vals.get('deadline'),
+ 'type': 'link',
+ 'partner_id': partner_id}, context=context)
+ vals['request_id'] = ret
+ return super(hr_evaluation_interview, self).create(cr, uid, vals, context=context)
+
def name_get(self, cr, uid, ids, context=None):
if not ids:
return []
reads = self.browse(cr, uid, ids, context=context)
res = []
for record in reads:
- name = record.request_id.survey_id.title
+ name = record.survey_id.title
res.append((record['id'], name))
return res
def survey_req_waiting_answer(self, cr, uid, ids, context=None):
- self.write(cr, uid, ids, { 'state': 'waiting_answer'}, context=context)
+ request_obj = self.pool.get('survey.user_input')
+ for interview in self.browse(cr, uid, ids, context=context):
+ request_obj.action_survey_resent(cr, uid, [interview.id], context=context)
+ self.write(cr, uid, interview.id, {'state': 'waiting_answer'}, context=context)
return True
def survey_req_done(self, cr, uid, ids, context=None):
- hr_eval_obj = self.pool.get('hr_evaluation.evaluation')
for id in self.browse(cr, uid, ids, context=context):
flag = False
wating_id = 0
if not id.evaluation_id.id:
- raise osv.except_osv(_('Warning!'),_("You cannot start evaluation without Appraisal."))
- records = hr_eval_obj.browse(cr, uid, [id.evaluation_id.id], context=context)[0].survey_request_ids
+ raise osv.except_osv(_('Warning!'), _("You cannot start evaluation without Appraisal."))
+ records = id.evaluation_id.survey_request_ids
for child in records:
if child.state == "draft":
wating_id = child.id
@@ -327,35 +346,29 @@ class hr_evaluation_interview(osv.osv):
flag = True
if not flag and wating_id:
self.survey_req_waiting_answer(cr, uid, [wating_id], context=context)
- self.write(cr, uid, ids, { 'state': 'done'}, context=context)
- return True
-
- def survey_req_draft(self, cr, uid, ids, context=None):
- self.write(cr, uid, ids, { 'state': 'draft'}, context=context)
+ self.write(cr, uid, ids, {'state': 'done'}, context=context)
return True
def survey_req_cancel(self, cr, uid, ids, context=None):
- self.write(cr, uid, ids, { 'state': 'cancel'}, context=context)
+ self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
return True
def action_print_survey(self, cr, uid, ids, context=None):
- """
- If response is available then print this response otherwise print survey form(print template of the survey).
+ """ If response is available then print this response otherwise print survey form (print template of the survey) """
+ context = context if context else {}
+ interview = self.browse(cr, uid, ids, context=context)[0]
+ survey_obj = self.pool.get('survey.survey')
+ response_obj = self.pool.get('survey.user_input')
+ response = response_obj.browse(cr, uid, interview.request_id.id, context=context)
+ context.update({'survey_token': response.token})
+ return survey_obj.action_print_survey(cr, uid, [interview.survey_id.id], context=context)
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of Survey IDs
- @param context: A standard dictionary for contextual values
- @return: Dictionary value for print survey form.
- """
- if context is None:
- context = {}
- record = self.browse(cr, uid, ids, context=context)
- record = record and record[0]
- context.update({'survey_id': record.survey_id.id, 'response_id': [record.response.id], 'response_no':0,})
- value = self.pool.get("survey").action_print_survey(cr, uid, ids, context=context)
- return value
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:1
+ def action_start_survey(self, cr, uid, ids, context=None):
+ context = context if context else {}
+ interview = self.browse(cr, uid, ids, context=context)[0]
+ survey_obj = self.pool.get('survey.survey')
+ response_obj = self.pool.get('survey.user_input')
+ # grab the token of the response and start surveying
+ response = response_obj.browse(cr, uid, interview.request_id.id, context=context)
+ context.update({'survey_token': response.token})
+ return survey_obj.action_start_survey(cr, uid, [interview.survey_id.id], context=context)
diff --git a/addons/hr_evaluation/hr_evaluation_data.xml b/addons/hr_evaluation/hr_evaluation_data.xml
index 2afb5200091..38171b0f733 100644
--- a/addons/hr_evaluation/hr_evaluation_data.xml
+++ b/addons/hr_evaluation/hr_evaluation_data.xml
@@ -1,4 +1,4 @@
-
+
@@ -16,1146 +16,7 @@
Manage employee reviews: you can define an appraisal campaign with several steps, with specific evaluation surveys according to hierarchy levels. Evaluations filled by employees may be exported as pdf files.
]]>
-
- Self Appraisal
- 20
-
-
-
- 5
- open
-
-
- Employee Appraisal Form
-
-
-
-
- Work Plan
-
-
-
-
- Employee Performance In Key Areas
-
-
- The appraiser should rate the employee’s major work accomplishments and performance according to the metric provided below :
- 1 - Significantly exceeds standards and expectations required of the position
- 2 - Exceeds standards and expectations
- 3 - Meet standards and expectations
- 4 - Did not meet standards and expectations
- 5 - Significantly below standards and expectations
-
-
- Professional Development And Performance Plan (optional)
-
-
- Identify professional, performance, or project objectives you recommend for employee’s continued career development over the coming year.
-
-
- Employee Comments
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Employee Information
-
- multiple_textboxes_diff_type
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Overall Purpose Of Employee Appraisal
-
- descriptive_text
- The comment you entered is in an invalid format.
- * To initiate a clear and open communication of performance expectations
-* To assist employees in their professional growth, through the identification of strengths and opportunities for development
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- At the outset of the appraisal time period
-
- descriptive_text
- The comment you entered is in an invalid format.
- * It is the joint responsibility of the employee and the supervisor (appraiser) to establish a feasible work plan for the coming year, including major employee responsibilities and corresponding benchmarks against which results will be evaluated.
-* Critical or key elements of performance and professional development needs (if any), should also be noted at this time
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- At the conclusion of the appraisal time period
-
- descriptive_text
- The comment you entered is in an invalid format.
- * The employee will be responsible for completing a draft of the Appraisal Form as a tool for self-appraisal and a starting point for the supervisor’s evaluation. The employee can add examples of achievements for each criterion.
-Once the form had been filled, the employee send it to his supervisor.
-
-* It is the primary responsibility of the supervisor to gather the necessary input from the appropriate sources of feedback (internal and/or external customers, peers). In case of collaboration with OpenERP SA Belgium, the supervisor must receive completed evaluation form from the employee's Belgian project manager.
-
-* The supervisor synthesizes and integrates all input into the completed appraisal. He motivates his evaluation in the ad hoc fields.
-
-* The employee may choose to offer comments or explanation regarding the completed review.
-
-* The supervisor send the form to the HR department in India and in Belgium.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Work Plan
-
- table
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Additional comments :
-
- comment
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Subject
-
- matrix_of_choices_only_one_ans
- Recommendations / Appraisals
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Supervisors only :
-
- matrix_of_choices_only_one_ans
- Recommendations / Appraisals
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Overall Performance Summary Rating
-
- descriptive_text
- The comment you entered is in an invalid format.
- including the project evaluation form (if any)
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Professional Development Objectives
-
- comment
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Personal Performance Objectives
-
- comment
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Project Objectives
-
- comment
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Use the following space to make any comments regarding the above performance evaluation.
-
- comment
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- Name
-
- char
-
-
-
- Position Title
-
- char
-
-
-
- Appraisal for Period
-
- char
-
-
-
- Date of Review
-
- datetime
-
-
-
- Appraiser
-
- char
-
-
-
- 1
- 1
- 1
-
-
-
- 1
- 1
- 2
-
-
-
- 1
- 1
- 3
-
-
-
- 1
- 1
- 4
-
-
-
- 1
- 1
- 5
-
-
-
- 1
- Ability to cope with multidisciplinary of team
-
-
-
-
- 1
- Enthusiasm & implication toward projects/assignments
-
-
-
-
- 1
- Compliance to internal rules and processes (timesheets completion, etc.)
-
-
-
-
- 1
- Team spirit : ability to work efficiently with peers, manage the conflicts with diplomacy
-
-
-
-
- 1
- Initiative and self autonomy
-
-
-
-
- 1
- Ability to follow and complete work as instructed
-
-
-
-
- 1
- Decision making
-
-
-
-
- 1
- Customer commitment
-
-
-
-
- 1
- Communication skills ( written & verbally): clearness, concision, exactitude
-
-
-
-
- 1
- Technical skills regarding to the job requirements
-
-
-
-
- 1
- Analytical and synthetic mind
-
-
-
-
- 1
- Promptness and attendance record
-
-
-
-
- 1
- Adaptability : Ability to adapt oneself to organizational changes while keeping efficiency
-
-
-
-
- 1
- Creativity and forward looking aptitude
-
-
-
-
- 1
- Time management : projects/tasks are completed on time
-
-
-
-
- 1
- 1
- 1
-
-
-
- 1
- 1
- 2
-
-
-
- 1
- 1
- 3
-
-
-
- 1
- 1
- 4
-
-
-
- 1
- 1
- 5
-
-
-
- 1
- Results of the bottom-up survey and mitigation actions to face technical, organizational, structural and/or relational issues
-
-
-
-
- 1
- Delegation : Ability to efficiently assign tasks to other people
-
-
-
-
- 1
- Leadership: create a challenging and motivating work environment aligned with the company's strategy
-
-
-
-
- 1
- Leadership: sustain subordinates in their professional growth
-
-
-
-
- 1
- Ability to manage planning resources, risks, budgets and deadlines
-
-
-
-
- 1
- 1
- Objectives
-
-
-
- 1
- 1
- Results
-
-
-
- 1
- 1
- Comments
-
-
-
- 1
- At the conclusion of the appraisal time period:
-
-
-
-
- 1
- At the outset of the appraisal time period:
-
-
-
-
-
- Employee Opinion
- 20
-
-
-
- 5
-
-
- Process
-
-
-
-
- Survey
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Employee Details
-
- multiple_textboxes_diff_type
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Engagement
-
- matrix_of_choices_only_one_ans
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Leadership
-
- matrix_of_choices_only_one_ans
-
-
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Effectiveness
-
- matrix_of_choices_only_one_ans
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Continuous Improvement
-
- matrix_of_choices_only_one_ans
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Openness
-
- matrix_of_choices_only_one_ans
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Miscellaneous
-
- matrix_of_choices_only_one_ans
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Additional comments :
-
- comment
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- At the supervisor's appraisal date
-
- descriptive_text
- The comment you entered is in an invalid format.
- * His direct reports will be invited through OpenERP to express a feedback on their supervisor's leadership and to give their opinion about their own engagement and effectiveness, the continuous improvement and openness in action in the company, ...
-
-* The employees will send back their anonymous answers to OpenERP. The data will be handled by the HR manager and a brief summary of the data will be sent to the concerned supervisor, to his team and to the supervisor's supervisor.
-* The appraiser should rate the employee’s major work accomplishments and performance according to the metric provided below :
-
- 1 - Significantly exceeds standards and expectations required of the position
- 2 - Exceeds standards and expectations
- 3 - Meet standards and expectations
- 4 - Did not meet standards and expectations
- 5 - Significantly below standards and expectations
-
-
-
- Other
-
-
-
-
- 1
- 1
- 1
-
-
-
- 1
- 1
- 2
-
-
-
- 1
- 1
- 3
-
-
-
- 1
- 1
- 4
-
-
-
- 1
- 1
- 5
-
-
-
- 1
- 1
- 1
-
-
-
- 1
- 1
- 2
-
-
-
- 1
- 1
- 3
-
-
-
- 1
- 1
- 4
-
-
-
- 1
- 1
- 5
-
-
-
- 1
- 1
- 1
-
-
-
- 1
- 1
- 2
-
-
-
- 1
- 1
- 3
-
-
-
- 1
- 1
- 4
-
-
-
- 1
- 1
- 5
-
-
-
- 1
- 1
- 1
-
-
-
- 1
- 1
- 2
-
-
-
- 1
- 1
- 3
-
-
-
- 1
- 1
- 4
-
-
-
- 1
- 1
- 5
-
-
-
- 1
- 1
- 1
-
-
-
- 1
- 1
- 2
-
-
-
- 1
- 1
- 3
-
-
-
- 1
- 1
- 4
-
-
-
- 1
- 1
- 5
-
-
-
- 1
- 1
- 1
-
-
-
- 1
- 1
- 2
-
-
-
- 1
- 1
- 3
-
-
-
- 1
- 1
- 4
-
-
-
- 1
- 1
- 5
-
-
-
- 1
- Demonstrates genuine concern for me as a person.
-
-
-
-
- 1
- I'm efficient at work and my achievements are successful.
-
-
-
-
- 1
- I am proud to tell others I work here.
-
-
-
-
- 0
- Name of your direct supervisor
-
- char
-
-
-
- 1
- Actions by Executive management show genuine interest in the well-being of employees.
-
-
-
-
- 1
- I know the company's values and live them.
-
-
-
-
- 1
- My work contributes towards the continuous improvement of the company, our services or products.
-
-
-
-
- 1
- I have enough work.
-
-
-
-
- 0
- Date
-
- datetime
-
-
-
- 1
- I consistently acquire new knowledge, skills or understanding through contact with my supervisor. He helps me growing my compete
-
-
-
-
- 1
- My job provides me with a sense of personal accomplishment.
-
-
-
-
- 1
- What I did several months ago is still of use to the company, the services or the products today.
-
-
-
-
- 1
- My best achievements have been communicated to the community, internally or to customers.
-
-
-
-
- 1
- I have the same opportunity to succeed as others with similar experiences, performance and educational background.
-
-
-
-
- 1
- Compared to similar jobs in other companies where I could work, my total compensation is:
-(Scale: Well below others, Below othe
-
-
-
-
- 1
- Overall, I believe the quality of products and/or services my workgroup delivers is improving.
-
-
-
-
- 1
- I would prefer to remain with this company even if a comparable job were available in another company.
-
-
-
-
- 1
- Listens and takes into account all ideas and do his best to put in place the best of these.
-
-
-
-
- 1
- I mostly work on value-added tasks for the company, the products or the services. (Value-added task : significant improvement pe
-
-
-
-
- 1
- Our workgroup identifies and reduces waste of time in our activities and processes.
-
-
-
-
- 1
- Taking everything into account, how satisfied are you with your current job?
-
-
-
-
- 1
- I understand the company strategy and how my workgroup supports it.
-
-
-
-
- 1
- I am willing to put in a great deal of effort beyond what is expected to help my workgroup succeed.
-
-
-
-
- 1
- I believe the information that I get from the person I report to.
-
-
-
-
-
-
@@ -1163,9 +24,8 @@ Once the form had been filled, the employee send it to his supervisor.
-
-
+
Send to Employee
@@ -1175,19 +35,17 @@ Once the form had been filled, the employee send it to his supervisor.
self
-
+
-
-
+
-
-
+
Run Employee Appraisal
diff --git a/addons/hr_evaluation/hr_evaluation_view.xml b/addons/hr_evaluation/hr_evaluation_view.xml
index 28bc4a6c96e..8f3998eeb42 100644
--- a/addons/hr_evaluation/hr_evaluation_view.xml
+++ b/addons/hr_evaluation/hr_evaluation_view.xml
@@ -21,24 +21,26 @@
hr_evaluation.plan
-
+
hr_evaluation.plan.form
@@ -58,9 +60,9 @@
formtree,form
-
+
-
+
hr.evaluation.interviewform
@@ -127,7 +129,7 @@
-
+
@@ -165,11 +167,9 @@
-
- Click to create a new interview request related to a personal evaluation.
+ Click to create a new interview request related to a personal evaluation.
Interview requests are usually generated automatically by
OpenERP according to an employee's appraisal plan. Each user
@@ -425,7 +397,7 @@
target="new" multi="True"
key2="client_action_multi"
context="{'default_composition_mode': 'mass_mail',
- 'default_body_text': 'Hello,\n\nKindly post your response for the survey interview.\n\nThanks',
+ 'default_body': 'Hello,\n\nKindly post your response for the survey interview.\n\nThanks',
'default_subject': 'Reminder to fill up Survey'}"/>
diff --git a/addons/hr_evaluation/report/hr_evaluation_report.py b/addons/hr_evaluation/report/hr_evaluation_report.py
index 36353b65dfb..ce6f381fb60 100644
--- a/addons/hr_evaluation/report/hr_evaluation_report.py
+++ b/addons/hr_evaluation/report/hr_evaluation_report.py
@@ -22,41 +22,43 @@
from openerp import tools
from openerp.osv import fields, osv
-class hr_evaluation_report(osv.osv):
+
+class hr_evaluation_report(osv.Model):
_name = "hr.evaluation.report"
_description = "Evaluations Statistics"
_auto = False
_columns = {
'create_date': fields.date('Create Date', readonly=True),
- 'delay_date':fields.float('Delay to Start', digits=(16,2),readonly=True),
- 'overpass_delay':fields.float('Overpassed Deadline', digits=(16,2), readonly=True),
+ 'delay_date': fields.float('Delay to Start', digits=(16, 2), readonly=True),
+ 'overpass_delay': fields.float('Overpassed Deadline', digits=(16, 2), readonly=True),
'day': fields.char('Day', size=128, readonly=True),
'deadline': fields.date("Deadline", readonly=True),
- 'request_id': fields.many2one('survey.request', 'Request_id', readonly=True),
+ 'request_id': fields.many2one('survey.user_input', 'Request_id', readonly=True),
'closed': fields.date("closed", readonly=True),
'year': fields.char('Year', size=4, readonly=True),
- 'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'),
- ('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'),
- ('10','October'), ('11','November'), ('12','December')], 'Month',readonly=True),
+ 'month': fields.selection([('01', 'January'), ('02', 'February'), ('03', 'March'), ('04', 'April'),
+ ('05', 'May'), ('06', 'June'), ('07', 'July'), ('08', 'August'), ('09', 'September'),
+ ('10', 'October'), ('11', 'November'), ('12', 'December')], 'Month', readonly=True),
'plan_id': fields.many2one('hr_evaluation.plan', 'Plan', readonly=True),
'employee_id': fields.many2one('hr.employee', "Employee", readonly=True),
'rating': fields.selection([
- ('0','Significantly bellow expectations'),
- ('1','Did not meet expectations'),
- ('2','Meet expectations'),
- ('3','Exceeds expectations'),
- ('4','Significantly exceeds expectations'),
+ ('0', 'Significantly bellow expectations'),
+ ('1', 'Did not meet expectations'),
+ ('2', 'Meet expectations'),
+ ('3', 'Exceeds expectations'),
+ ('4', 'Significantly exceeds expectations'),
], "Overall Rating", readonly=True),
- 'nbr':fields.integer('# of Requests', readonly=True),
+ 'nbr': fields.integer('# of Requests', readonly=True),
'state': fields.selection([
- ('draft','Draft'),
- ('wait','Plan In Progress'),
- ('progress','Final Validation'),
- ('done','Done'),
- ('cancel','Cancelled'),
- ], 'Status',readonly=True),
+ ('draft', 'Draft'),
+ ('wait', 'Plan In Progress'),
+ ('progress', 'Final Validation'),
+ ('done', 'Done'),
+ ('cancel', 'Cancelled'),
+ ], 'Status', readonly=True),
}
_order = 'create_date desc'
+
def init(self, cr):
tools.drop_view_if_exists(cr, 'hr_evaluation_report')
cr.execute("""
diff --git a/addons/hr_evaluation/security/ir.model.access.csv b/addons/hr_evaluation/security/ir.model.access.csv
index 1f22e3b5d16..3fb1425651c 100644
--- a/addons/hr_evaluation/security/ir.model.access.csv
+++ b/addons/hr_evaluation/security/ir.model.access.csv
@@ -6,37 +6,20 @@ access_hr_evaluation_plan_phase_user,hr_evaluation.plan.phase.user,model_hr_eval
access_hr_evaluation_interview_user,hr.evaluation.interview.user,model_hr_evaluation_interview,base.group_hr_user,1,1,1,1
access_hr_evaluation_interview_employee,hr.evaluation.interview.employee,model_hr_evaluation_interview,base.group_user,1,1,1,0
access_hr_evaluation_report,hr.evaluation.report,model_hr_evaluation_report,base.group_hr_manager,1,1,1,1
-access_survey_type_hr_manager,survey.type,survey.model_survey_type,base.group_hr_manager,1,1,1,1
-access_survey_hr_manager,survey.hr.manager,survey.model_survey,base.group_hr_manager,1,1,1,1
-access_survey_history_manager,survey.history,survey.model_survey_history,base.group_hr_manager,1,1,1,1
+access_survey_hr_manager,survey.hr.manager,survey.model_survey_survey,base.group_hr_manager,1,1,1,1
access_survey_question_hr_manager,survey.question,survey.model_survey_question,base.group_hr_manager,1,1,1,1
-access_survey_question_column_heading_hr_manager,survey.question.column.heading,survey.model_survey_question_column_heading,base.group_hr_manager,1,1,1,1
-access_survey_answer_hr_manager,survey.answer,survey.model_survey_answer,base.group_hr_manager,1,1,1,1
-access_survey_response_hr_manager,survey.response,survey.model_survey_response,base.group_hr_manager,1,1,1,1
-access_survey_response_line_hr_manager,survey.response.line,survey.model_survey_response_line,base.group_hr_manager,1,1,1,1
-access_survey_tbl_column_heading_hr_manager,survey.tbl.column.heading,survey.model_survey_tbl_column_heading,base.group_hr_manager,1,1,1,1
-access_survey_response_answer_hr_manager,survey.response.answer,survey.model_survey_response_answer,base.group_hr_manager,1,1,1,1
-access_survey_request_hr_manager,survey.request,survey.model_survey_request,base.group_hr_manager,1,1,1,1
-access_survey_answer_hr_user,survey.answer.hr.user,survey.model_survey_answer,base.group_hr_user,1,1,1,0
-access_survey_response_answer_hr_user,survey.response.answer.hr.user,survey.model_survey_response_answer,base.group_hr_user,1,1,1,0
-access_survey_type_hr_user,survey.type.hr.user,survey.model_survey_type,base.group_hr_user,1,1,1,0
+access_survey_question_column_heading_hr_manager,survey.question.column.heading,survey.model_survey_label,base.group_hr_manager,1,1,1,1
+access_survey_response_hr_manager,survey.response,survey.model_survey_user_input,base.group_hr_manager,1,1,1,1
+access_survey_response_line_hr_manager,survey.response.line,survey.model_survey_user_input_line,base.group_hr_manager,1,1,1,1
access_survey_question_hr_user,survey.question.hr.user,survey.model_survey_question,base.group_hr_user,1,1,1,0
access_survey_page_hr_user,survey.page.hr.user,survey.model_survey_page,base.group_hr_user,1,1,1,1
-access_survey_response_hr_user,survey.response.hr.user,survey.model_survey_response,base.group_hr_user,1,1,1,0
-access_survey_history_hr_user,survey.history.hr.user,survey.model_survey_history,base.group_hr_user,1,1,1,0
-access_survey_request_hr_user,survey.request.hr.user,survey.model_survey_request,base.group_hr_user,1,1,1,0
-access_survey_question_column_heading_hr_user,survey.question.column.heading.hr.user,survey.model_survey_question_column_heading,base.group_hr_user,1,1,1,0
-access_survey_response_line_hr_user,survey.response.line.hr.user,survey.model_survey_response_line,base.group_hr_user,1,1,1,0
-access_survey_tbl_column_heading_hr_user,survey.tbl.column.heading.hr.user,survey.model_survey_tbl_column_heading,base.group_hr_user,1,1,1,0
+access_survey_response_hr_user,survey.response.hr.user,survey.model_survey_user_input,base.group_hr_user,1,1,1,0
+access_survey_question_column_heading_hr_user,survey.question.column.heading.hr.user,survey.model_survey_label,base.group_hr_user,1,1,1,0
+access_survey_response_line_hr_user,survey.response.line.hr.user,survey.model_survey_user_input_line,base.group_hr_user,1,1,1,0
access_calendar_attendee_survey_user,base.calendar.calendar.attendee.survey.user,calendar.model_calendar_attendee,base.group_survey_user,1,1,1,0
-access_calendar_attendee_tool_user,base.calendar.calendar.attendee.tool.user,calendar.model_calendar_attendee,base.group_tool_user,1,1,1,0
-access_survey_request_hr_employee,survey.request.hr.employee,survey.model_survey_request,base.group_user,1,1,1,0
-access_survey_hr_employee,survey.hr.employee,survey.model_survey,base.group_user,1,1,0,0
+access_survey_hr_employee,survey.hr.employee,survey.model_survey_survey,base.group_user,1,1,0,0
access_survey_page_hr_employee,survey.page.hr.employee,survey.model_survey_page,base.group_user,1,0,0,0
-access_survey_answer_hr_employee,survey.answer.employee,survey.model_survey_answer,base.group_user,1,0,0,0
access_survey_question_hr_employee,survey.question.employee,survey.model_survey_question,base.group_user,1,0,0,0
-access_survey_response_hr_employee,survey.response.employee,survey.model_survey_response,base.group_user,1,1,1,0
-access_survey_question_column_heading_hr_employee,survey.question.column.heading.employee,survey.model_survey_question_column_heading,base.group_user,1,0,0,0
-access_survey_response_line_hr_employee,survey.response.line.employee,survey.model_survey_response_line,base.group_user,1,1,1,0
-access_survey_response_answer_hr_employee,survey.response.answer.hr.employee,survey.model_survey_response_answer,base.group_user,1,1,1,0
-access_survey_tbl_column_heading_hr_employee,survey.tbl.column.heading,survey.model_survey_tbl_column_heading,base.group_user,1,1,1,0
\ No newline at end of file
+access_survey_response_hr_employee,survey.response.employee,survey.model_survey_user_input,base.group_user,1,1,1,0
+access_survey_question_column_heading_hr_employee,survey.question.column.heading.employee,survey.model_survey_label,base.group_user,1,0,0,0
+access_survey_response_line_hr_employee,survey.response.line.employee,survey.model_survey_user_input_line,base.group_user,1,1,1,0
\ No newline at end of file
diff --git a/addons/hr_evaluation/survey_data_appraisal.xml b/addons/hr_evaluation/survey_data_appraisal.xml
new file mode 100644
index 00000000000..d3f83f91ba5
--- /dev/null
+++ b/addons/hr_evaluation/survey_data_appraisal.xml
@@ -0,0 +1,676 @@
+
+
+
+
+
+ Employee Appraisal Form
+
+ hr_evaluation
+
+
+ <p> </p>
+ <p> </p>
+
+
+
+ Employee Appraisal Form
+
+ 1
+ <h2>Overall Purpose Of Employee Appraisal</h2>
+<ul><li>To initiate a clear and open communication of performance expectations
+<li>To assist employees in their professional growth, through the identification of strengths and opportunities for
+development</ul>
+<h2>At the outset of the appraisal time period</h2>
+<ul><li>It is the joint responsibility of the employee and the supervisor (appraiser) to establish a feasible work plan for the
+coming year, including major employee responsibilities and corresponding benchmarks against which results will be
+evaluated.
+<li>Critical or key elements of performance and professional development needs (if any), should also be noted at this time</ul>
+<h2>At the conclusion of the appraisal time period</h2>
+<ul><li>The employee will be responsible for completing a draft of the Appraisal Form as a tool for self-appraisal and a starting
+point for the supervisor’s evaluation. The employee can add examples of achievements for each criterion.
+Once the form had been filled, the employee send it to his supervisor.
+<li>It is the primary responsibility of the supervisor to gather the necessary input from the appropriate sources of feedback
+(internal and/or external customers, peers). In case of collaboration with OpenERP SA Belgium, the supervisor must
+receive completed evaluation form from the employee's Belgian project manager.
+<li>The supervisor synthesizes and integrates all input into the completed appraisal. He motivates his evaluation in the ad
+hoc fields.
+<li>The employee may choose to offer comments or explanation regarding the completed review.
+<li>The supervisor send the form to the HR department in India and in Belgium</ul>
+
+
+
+ 1
+ Name
+ textbox
+
+
+
+
+ 2
+ Position Title
+ textbox
+
+
+
+
+ 3
+ Appraisal for Period
+ textbox
+
+
+
+
+ 4
+ Date of review
+ textbox
+
+
+
+
+ 5
+ Appraiser
+ textbox
+
+
+
+
+ Work Plan
+
+ 2
+ <p> </p>
+
+
+
+ 1
+ Objectives
+ free_text
+
+
+
+
+ 2
+ Results
+ free_text
+
+
+
+
+ 3
+ Additional Comments
+ free_text
+
+
+
+ Employee Performance in Key Areas
+
+ 3
+ The appraiser should rate the employee’s major work accomplishments and performance according to the metric provided
+below:<ol>
+<li> Significantly exceeds standards and expectations required of the position
+<li> Exceeds standards and expectations
+<li> Meet standards and expectations
+<li> Did not meet standards and expectations
+<li> Significantly below standards and expectations</ol>
+
+
+
+ 1
+ Subject
+ matrix
+ simple
+
+
+
+
+ 1
+ 1
+
+
+
+ 2
+ 2
+
+
+
+ 3
+ 3
+
+
+
+ 4
+ 4
+
+
+
+ 5
+ 5
+
+
+
+ 1
+ Ability to cope with multidisciplinarity of team
+
+
+
+ 2
+ Enthusiasm & implication toward projects/assignments
+
+
+
+ 3
+ Compliance to internal rules and processes (timesheets completion, etc.)
+
+
+
+ 4
+ Team spirit: ability to work efficiently with peers, manage the conflicts with diplomacy
+
+
+
+ 5
+ Initiative and self autonomy
+
+
+
+ 6
+ Ability to follow and complete work as instructed
+
+
+
+ 7
+ Decision making
+
+
+
+ 8
+ Customer commitment
+
+
+
+ 9
+ Communication skills (written & verbally): clearness, concision, exactitude
+
+
+
+ 10
+ Technical skills regarding to the job requirements
+
+
+
+ 11
+ Analytical and synthetic mind
+
+
+
+ 12
+ Promptness and attendance record
+
+
+
+ 13
+ Adaptability: Ability to adapt oneself to organizational changes while keeping efficiency
+
+
+
+ 14
+ Creativity and forward looking aptitude
+
+
+
+ 15
+ Time management: projects/tasks are completed on time
+
+
+
+ 2
+ Supervisors only
+ matrix
+ simple
+
+
+
+ 1
+ 1
+
+
+
+ 2
+ 2
+
+
+
+ 3
+ 3
+
+
+
+ 4
+ 4
+
+
+
+ 5
+ 5
+
+
+
+ 1
+ Results of the bottom-up survey and mitigation actions to face technical, organizational, structural and/or relational issues
+
+
+
+ 2
+ Delegation: Ability to efficiently assign tasks to other people
+
+
+
+ 3
+ Leadership: create a challenging and motivating work environment aligned with the company's strategy
+
+
+
+ 4
+ Leadership: sustain subordinates in their professional growth
+
+
+
+ 5
+ Ability to manage planning resources, risks, budgets and deadlines
+
+
+
+ Professional Development and Performance Plan
+
+ 4
+ <p>Identify professional, performance, or project objectives you recommend for employee’s continued career development
+over the coming year.</p>
+
+
+
+ 1
+ Professional Development Objectives
+ free_text
+
+
+
+ 2
+ Personal Performance Objectives
+ free_text
+
+
+
+ 3
+ Project Objectives
+ free_text
+
+
+
+ Employee Comments
+
+ <p></p>
+ 5
+
+
+
+ 1
+ Use the following space to make any comments regarding the above performance evaluation.
+ free_text
+
+
+
+ Employee Opinion Form
+
+ hr_evaluation
+
+
+ <p> </p>
+ <p> </p>
+
+
+
+ Appraisal Process
+
+ 1
+ <h2>At the supervisor's appraisal date</h2>
+<p>His direct reports will be invited through OpenERP to express a feedback on their supervisor's leadership and to give their opinion about their own engagement and effectiveness, the continuous improvement and openness in action in thecompany...</p>
+<p>The employees will send back their anonymous answers to OpenERP. The data will be handled by the HR manager and a brief summary of the data will be sent to the concerned supervisor, to his team and to the supervisor's supervisor.</p>
+<p>The appraiser should rate the employee's major work accomplishments and performance according to the metric provided below
+<ol>
+<li>Significantly exceeds standards and expectations required of the position</li>
+<li>Exceeds standards and expectations</li>
+<li>Meet standards and expectations</li>
+<li>Did not meet standards and expectations</li>
+<li>Significantly below standards and expectations</li>
+</ol></p>
+
+
+
+ 1
+ Name of your direct supervisor
+ textbox
+
+
+
+
+ 2
+ Date
+ textbox
+
+
+
+
+ Evaluation
+
+ 2
+ <p> </p>
+
+
+
+ 1
+ Engagement
+ matrix
+ simple
+
+
+
+ 1
+ 1
+
+
+
+ 2
+ 2
+
+
+
+ 3
+ 3
+
+
+
+ 4
+ 4
+
+
+
+ 5
+ 5
+
+
+
+ 1
+ I am proud to tell others I work here
+
+
+
+ 2
+ My job provides me with a sense of personal accomplishment
+
+
+
+ 3
+ I would prefer to remain with this company even if a comparable job were available in another company
+
+
+
+ 4
+ Taking everything into account, how satisfied are you with your current job?
+
+
+
+ 5
+ I am willing to put in a great deal of effort beyond what is expected to help my workgroup succeed
+
+
+
+ 2
+ Leadership
+ matrix
+ simple
+
+
+
+ 1
+ 1
+
+
+
+ 2
+ 2
+
+
+
+ 3
+ 3
+
+
+
+ 4
+ 4
+
+
+
+ 5
+ 5
+
+
+
+ 1
+ Demonstrates genuine concern for me as a person
+
+
+
+ 2
+ I consistently acquire new knowledge, skills or understanding through contact with my supervisor. He helps me growing my compete
+
+
+
+ 3
+ Listens and takes into account all ideas and do his best to put in place the best of these
+
+
+
+ 4
+ I believe the information that I get from the person I report to.
+
+
+
+ 3
+ Effectiveness
+ matrix
+ simple
+
+
+
+ 1
+ 1
+
+
+
+ 2
+ 2
+
+
+
+ 3
+ 3
+
+
+
+ 4
+ 4
+
+
+
+ 5
+ 5
+
+
+
+ 1
+ I'm efficient at work and my achievements are successful
+
+
+
+ 2
+ I have enough work
+
+
+
+ 3
+ I mostly work on value-added tasks for the company, the products or the services
+
+
+
+ 4
+ Continuous Improvement
+ matrix
+ simple
+
+
+
+ 1
+ 1
+
+
+
+ 2
+ 2
+
+
+
+ 3
+ 3
+
+
+
+ 4
+ 4
+
+
+
+ 5
+ 5
+
+
+
+ 1
+ My work contributes towards the continuous improvement of the company, our services or products
+
+
+
+ 2
+ What I did several months ago is still of use to the company, the services or the products today
+
+
+
+ 3
+ Overall, I believe the quality of products and/or services my workgroup delivers is improving
+
+
+
+ 4
+ Our workgroup identifies and reduces waste of time in our activities and processes
+
+
+
+ 5
+ Openness
+ matrix
+ simple
+
+
+
+ 1
+ 1
+
+
+
+ 2
+ 2
+
+
+
+ 3
+ 3
+
+
+
+ 4
+ 4
+
+
+
+ 5
+ 5
+
+
+
+ 1
+ I know the company's values and live them
+
+
+
+ 2
+ My best achievements have been communicated to the community, internally or to customers
+
+
+
+ 6
+ Miscellaneous
+ matrix
+ simple
+
+
+
+ 1
+ 1
+
+
+
+ 2
+ 2
+
+
+
+ 3
+ 3
+
+
+
+ 4
+ 4
+
+
+
+ 5
+ 5
+
+
+
+ 1
+ Actions by Executive management show genuine interest in the well-being of employees
+
+
+
+ 2
+ I have the same opportunity to succeed as others with similar experiences, performance and educational background
+
+
+
+ 3
+ Compared to similar jobs in other companies where I could work, my total compensation...
+
+
+
+ 4
+ I understand the company strategy and how my workgroup supports it
+
+
+
+ 7
+ Additional comments
+ free_text
+
+
+
diff --git a/addons/hr_evaluation/test/hr_evalution_demo.yml b/addons/hr_evaluation/test/hr_evalution_demo.yml
index 8c62969dea6..d6a7a327c66 100644
--- a/addons/hr_evaluation/test/hr_evalution_demo.yml
+++ b/addons/hr_evaluation/test/hr_evalution_demo.yml
@@ -1,6 +1,6 @@
--
- !record {model: hr.employee, id: hr.employee_fp, view: False}:
- evaluation_plan_id: hr_evaluation_plan_managersevaluationplan0
--
- !record {model: hr_evaluation.evaluation, id: hr_evaluation_evaluation_0, view: False}:
- plan_id: hr_evaluation.hr_evaluation_plan_managersevaluationplan0
\ No newline at end of file
+# -
+# !record {model: hr.employee, id: hr.employee_fp, view: False}:
+# evaluation_plan_id: hr_evaluation_plan_managersevaluationplan0
+# -
+# !record {model: hr_evaluation.evaluation, id: hr_evaluation_evaluation_0, view: False}:
+# plan_id: hr_evaluation.hr_evaluation_plan_managersevaluationplan0
\ No newline at end of file
diff --git a/addons/hr_evaluation/test/test_hr_evaluation.yml b/addons/hr_evaluation/test/test_hr_evaluation.yml
index 3244e37302e..d9d6c8edd49 100644
--- a/addons/hr_evaluation/test/test_hr_evaluation.yml
+++ b/addons/hr_evaluation/test/test_hr_evaluation.yml
@@ -1,108 +1,103 @@
--
- I set the "Employee Evaluation" survey in open state.
--
- !python {model: survey}: |
- self.survey_open(cr, uid, [ref("survey_2")], context)
--
- I check that state of "Employee Evaluation" survey is Open.
--
- !assert {model: survey, id: survey_2, severity: error, string: Survey should be in OPen state}:
- - state == 'open'
--
- I start the evaluation process by click on "Start Evaluation" button.
--
- !python {model: hr_evaluation.evaluation}: |
- self.button_plan_in_progress(cr, uid, [ref('hr_evaluation_evaluation_0')])
--
- I check that state is "Plan in progress".
--
- !assert {model: hr_evaluation.evaluation, id: hr_evaluation_evaluation_0, severity: error, string: Evaluation should be 'Plan in progress' state}:
- - state == 'wait'
--
- I find a mistake on evaluation form. So I cancel the evaluation and again start it.
--
- !python {model: hr_evaluation.evaluation}: |
- evaluation = self.browse(cr, uid, ref('hr_evaluation_evaluation_0') , context)
- self.button_cancel(cr, uid, [ref('hr_evaluation_evaluation_0')])
- assert evaluation.state == 'cancel', 'Evaluation should be in cancel state'
- self.button_draft(cr, uid, [ref('hr_evaluation_evaluation_0')])
- evaluation = self.browse(cr, uid, ref('hr_evaluation_evaluation_0') , context)
- assert evaluation.state == 'draft', 'Evaluation should be in draft state'
- self.button_plan_in_progress(cr, uid, [ref('hr_evaluation_evaluation_0')])
--
- I check that state is "Plan in progress" and "Interview Request" record is created
--
- !python {model: hr_evaluation.evaluation}: |
- interview_obj = self.pool.get('hr.evaluation.interview')
- evaluation = self.browse(cr, uid, ref('hr_evaluation_evaluation_0') , context)
- assert evaluation.state == 'wait', "Evaluation should be 'Plan in progress' state"
- interview_ids = interview_obj.search(cr, uid, [('evaluation_id','=', ref('hr_evaluation_evaluation_0'))])
- assert len(interview_ids), "Interview evaluation survey not created"
--
- Give answer of the first page in "Employee Evaluation" survey.
--
- !python {model: survey.question.wiz}: |
- name_wiz_obj=self.pool.get('survey.name.wiz')
- interview_obj = self.pool.get('hr.evaluation.interview')
- interview_ids = interview_obj.search(cr, uid, [('evaluation_id','=', ref('hr_evaluation_evaluation_0'))])
- assert len(interview_ids), "Interview evaluation survey not created"
- ctx = {'active_model':'hr.evaluation.interview', 'active_id': interview_ids[0], 'active_ids': [interview_ids], 'survey_id': ref("survey_2")}
- name_id = name_wiz_obj.create(cr, uid, {'survey_id': ref("survey_2")})
- ctx ["sur_name_id"] = name_id
- self.create(cr, uid, {str(ref("survey_question_2")) +"_" +str(ref("survey_answer_1")) + "_multi" :'tpa',
- str(ref("survey_question_2")) +"_" +str(ref("survey_answer_10")) + "_multi" :'application eng',
- str(ref("survey_question_2")) +"_" +str(ref("survey_answer_20")) + "_multi" :'3',
- str(ref("survey_question_2")) +"_" +str(ref("survey_answer_25")) + "_multi" :'2011-12-02 16:42:00',
- str(ref("survey_question_2")) +"_" +str(ref("survey_answer_43")) + "_multi" :'HR',
- }, context = ctx)
--
- I close this Evaluation survey by giving answer of questions.
--
- !python {model: hr_evaluation.evaluation}: |
- interview_obj = self.pool.get('hr.evaluation.interview')
- evaluation = self.browse(cr, uid, ref('hr_evaluation_evaluation_0'))
- interview_obj.survey_req_done(cr, uid, [r.id for r in evaluation.survey_request_ids])
- for survey in evaluation.survey_request_ids:
- interview = interview_obj.browse(cr, uid, survey.id, context)
- assert interview.state == "done", 'survey must be in done state'
--
- I print the evaluation.
--
- !python {model: hr_evaluation.evaluation}: |
- evaluation = self.browse(cr, uid, ref('hr_evaluation_evaluation_0'))
- self.pool.get('hr.evaluation.interview').action_print_survey(cr, uid, [r.id for r in evaluation.survey_request_ids])
--
- I click on "Final Validation" button to finalise evaluation.
--
- !python {model: hr_evaluation.evaluation}: |
- self.button_final_validation(cr, uid, [ref("hr_evaluation_evaluation_0")])
--
- I check that state is "Waiting Appreciation".
--
- !assert {model: hr_evaluation.evaluation, id: hr_evaluation_evaluation_0}:
- - state == 'progress'
--
- Give Rating "Meet expectations" by selecting overall Rating.
--
- !record {model: hr_evaluation.evaluation, id: hr_evaluation_evaluation_0}:
- rating: '2'
--
- I close this Evaluation by click on "Done" button of this wizard.
--
- !python {model: hr_evaluation.evaluation}: |
- self.button_done(cr, uid, [ref("hr_evaluation_evaluation_0")])
--
- I check that state of Evaluation is done.
--
- !assert {model: hr_evaluation.evaluation, id: hr_evaluation_evaluation_0, severity: error, string: Evaluation should be in done state}:
- - state == 'done'
--
- Print Evaluations Statistics Report
--
- !python {model: hr.evaluation.report}: |
- import os, time
- from openerp import tools
- ctx={}
- data_dict={'state': 'done', 'rating': 2, 'employee_id': ref("hr.employee_fp")}
- from openerp.tools import test_reports
- test_reports.try_report_action(cr, uid, 'hr_evaluation_evaluation_0',wiz_data=data_dict, context=ctx, our_module='hr_evaluation')
+# -
+# I check that state of "Employee Evaluation" survey is Open.
+# -
+# !assert {model: survey.survey, id: appraisal_form, severity: error, string: Survey should be in 'open' state}:
+# - state == 'open'
+# -
+# I start the evaluation process by click on "Start Evaluation" button.
+# -
+# !python {model: hr_evaluation.evaluation}: |
+# self.button_plan_in_progress(cr, uid, [ref('hr_evaluation_evaluation_0')])
+# -
+# I check that state is "Plan in progress".
+# -
+# !assert {model: hr_evaluation.evaluation, id: hr_evaluation_evaluation_0, severity: error, string: Evaluation should be 'Plan in progress' state}:
+# - state == 'wait'
+# -
+# I find a mistake on evaluation form. So I cancel the evaluation and again start it.
+# -
+# !python {model: hr_evaluation.evaluation}: |
+# evaluation = self.browse(cr, uid, ref('hr_evaluation_evaluation_0') , context)
+# self.button_cancel(cr, uid, [ref('hr_evaluation_evaluation_0')])
+# assert evaluation.state == 'cancel', 'Evaluation should be in cancel state'
+# self.button_draft(cr, uid, [ref('hr_evaluation_evaluation_0')])
+# evaluation = self.browse(cr, uid, ref('hr_evaluation_evaluation_0') , context)
+# assert evaluation.state == 'draft', 'Evaluation should be in draft state'
+# self.button_plan_in_progress(cr, uid, [ref('hr_evaluation_evaluation_0')])
+# -
+# I check that state is "Plan in progress" and "Interview Request" record is created
+# -
+# !python {model: hr_evaluation.evaluation}: |
+# interview_obj = self.pool.get('hr.evaluation.interview')
+# evaluation = self.browse(cr, uid, ref('hr_evaluation_evaluation_0') , context)
+# assert evaluation.state == 'wait', "Evaluation should be 'Plan in progress' state"
+# interview_ids = interview_obj.search(cr, uid, [('evaluation_id','=', ref('hr_evaluation_evaluation_0'))])
+# assert len(interview_ids), "Interview evaluation survey not created"
+# -
+# Give answer of the first page in "Employee Evaluation" survey.
+# -
+# !python {model: survey.question.wiz}: |
+# name_wiz_obj=self.pool.get('survey.name.wiz')
+# interview_obj = self.pool.get('hr.evaluation.interview')
+# interview_ids = interview_obj.search(cr, uid, [('evaluation_id','=', ref('hr_evaluation_evaluation_0'))])
+# assert len(interview_ids), "Interview evaluation survey not created"
+# ctx = {'active_model':'hr.evaluation.interview', 'active_id': interview_ids[0], 'active_ids': [interview_ids], 'survey_id': ref("survey_2")}
+# name_id = name_wiz_obj.create(cr, uid, {'survey_id': ref("survey_2")})
+# ctx ["sur_name_id"] = name_id
+# self.create(cr, uid, {str(ref("survey_question_2")) +"_" +str(ref("survey_answer_1")) + "_multi" :'tpa',
+# str(ref("survey_question_2")) +"_" +str(ref("survey_answer_10")) + "_multi" :'application eng',
+# str(ref("survey_question_2")) +"_" +str(ref("survey_answer_20")) + "_multi" :'3',
+# str(ref("survey_question_2")) +"_" +str(ref("survey_answer_25")) + "_multi" :'2011-12-02 16:42:00',
+# str(ref("survey_question_2")) +"_" +str(ref("survey_answer_43")) + "_multi" :'HR',
+# }, context = ctx)
+# -
+# I close this Evaluation survey by giving answer of questions.
+# -
+# !python {model: hr_evaluation.evaluation}: |
+# interview_obj = self.pool.get('hr.evaluation.interview')
+# evaluation = self.browse(cr, uid, ref('hr_evaluation_evaluation_0'))
+# interview_obj.survey_req_done(cr, uid, [r.id for r in evaluation.survey_request_ids])
+# for survey in evaluation.survey_request_ids:
+# interview = interview_obj.browse(cr, uid, survey.id, context)
+# assert interview.state == "done", 'survey must be in done state'
+# -
+# I print the evaluation.
+# -
+# !python {model: hr_evaluation.evaluation}: |
+# evaluation = self.browse(cr, uid, ref('hr_evaluation_evaluation_0'))
+# self.pool.get('hr.evaluation.interview').action_print_survey(cr, uid, [r.id for r in evaluation.survey_request_ids])
+# -
+# I click on "Final Validation" button to finalise evaluation.
+# -
+# !python {model: hr_evaluation.evaluation}: |
+# self.button_final_validation(cr, uid, [ref("hr_evaluation_evaluation_0")])
+# -
+# I check that state is "Waiting Appreciation".
+# -
+# !assert {model: hr_evaluation.evaluation, id: hr_evaluation_evaluation_0}:
+# - state == 'progress'
+# -
+# Give Rating "Meet expectations" by selecting overall Rating.
+# -
+# !record {model: hr_evaluation.evaluation, id: hr_evaluation_evaluation_0}:
+# rating: '2'
+# -
+# I close this Evaluation by click on "Done" button of this wizard.
+# -
+# !python {model: hr_evaluation.evaluation}: |
+# self.button_done(cr, uid, [ref("hr_evaluation_evaluation_0")])
+# -
+# I check that state of Evaluation is done.
+# -
+# !assert {model: hr_evaluation.evaluation, id: hr_evaluation_evaluation_0, severity: error, string: Evaluation should be in done state}:
+# - state == 'done'
+# -
+# Print Evaluations Statistics Report
+# -
+# !python {model: hr.evaluation.report}: |
+# import os, time
+# from openerp import tools
+# ctx={}
+# data_dict={'state': 'done', 'rating': 2, 'employee_id': ref("hr.employee_fp")}
+# from openerp.tools import test_reports
+# test_reports.try_report_action(cr, uid, 'hr_evaluation_evaluation_0',wiz_data=data_dict, context=ctx, our_module='hr_evaluation')
diff --git a/addons/hr_recruitment/__openerp__.py b/addons/hr_recruitment/__openerp__.py
index e6c94b4245f..27c7d194b74 100644
--- a/addons/hr_recruitment/__openerp__.py
+++ b/addons/hr_recruitment/__openerp__.py
@@ -25,7 +25,7 @@
'version': '1.0',
'category': 'Human Resources',
'sequence': 25,
- 'summary': 'Jobs, Recruitment, Applications, Job Interviews',
+ 'summary': 'Jobs, Recruitment, Applications, Job Interviews, Surveys',
'description': """
Manage job positions and the recruitment process
================================================
@@ -37,7 +37,8 @@ You can define the different phases of interviews and easily rate the applicant
""",
'author': 'OpenERP SA',
'website': 'http://www.openerp.com',
- 'images': ['images/hr_recruitment_analysis.jpeg','images/hr_recruitment_applicants.jpeg','static/src/img/down1.png'],
+ 'images': ['images/hr_recruitment_analysis.jpeg',
+ 'images/hr_recruitment_applicants.jpeg'],
'depends': [
'decimal_precision',
'hr',
@@ -56,6 +57,7 @@ You can define the different phases of interviews and easily rate the applicant
'board_hr_recruitment_statistical_view.xml',
'hr_recruitment_installer_view.xml',
'res_config_view.xml',
+ 'survey_data_recruitment.xml',
'hr_recruitment_data.xml',
],
'demo': ['hr_recruitment_demo.xml'],
@@ -63,10 +65,8 @@ You can define the different phases of interviews and easily rate the applicant
'static/src/js/job_position.js',
],
'test': ['test/recruitment_process.yml'],
- 'css':['static/src/css/job_position.css'],
+ 'css': ['static/src/css/job_position.css'],
'installable': True,
'auto_install': False,
'application': True,
}
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/hr_recruitment/hr_recruitment.py b/addons/hr_recruitment/hr_recruitment.py
index 20e9e0930cc..ac11ef5e81d 100644
--- a/addons/hr_recruitment/hr_recruitment.py
+++ b/addons/hr_recruitment/hr_recruitment.py
@@ -211,8 +211,8 @@ class hr_applicant(osv.Model):
'partner_mobile': fields.char('Mobile', size=32),
'type_id': fields.many2one('hr.recruitment.degree', 'Degree'),
'department_id': fields.many2one('hr.department', 'Department'),
- 'survey': fields.related('job_id', 'survey_id', type='many2one', relation='survey', string='Survey'),
- 'response': fields.integer("Response"),
+ 'survey': fields.related('job_id', 'survey_id', type='many2one', relation='survey.survey', string='Survey'),
+ 'response_id': fields.many2one('survey.user_input', "Response", ondelete='set null', oldname="response"),
'reference': fields.char('Referred By', size=128),
'source_id': fields.many2one('hr.recruitment.source', 'Source'),
'day_open': fields.function(_compute_day, string='Days to Open', \
@@ -311,24 +311,34 @@ class hr_applicant(osv.Model):
}
return res
- def action_print_survey(self, cr, uid, ids, context=None):
- """
- If response is available then print this response otherwise print survey form(print template of the survey).
+ def action_start_survey(self, cr, uid, ids, context=None):
+ context = context if context else {}
+ applicant = self.browse(cr, uid, ids, context=context)[0]
+ survey_obj = self.pool.get('survey.survey')
+ response_obj = self.pool.get('survey.user_input')
+ # create a response and link it to this applicant
+ if not applicant.response_id:
+ response_id = response_obj.create(cr, uid, {'survey_id': applicant.survey.id, 'partner_id': applicant.partner_id.id}, context=context)
+ self.write(cr, uid, ids[0], {'response_id': response_id}, context=context)
+ else:
+ response_id = applicant.response_id.id
+ # grab the token of the response and start surveying
+ response = response_obj.browse(cr, uid, response_id, context=context)
+ context.update({'survey_token': response.token})
+ return survey_obj.action_start_survey(cr, uid, [applicant.survey.id], context=context)
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of Survey IDs
- @param context: A standard dictionary for contextual values
- @return: Dictionary value for print survey form.
- """
- if context is None:
- context = {}
- record = self.browse(cr, uid, ids, context=context)
- record = record and record[0]
- context.update({'survey_id': record.survey.id, 'response_id': [record.response], 'response_no': 0, })
- value = self.pool.get("survey").action_print_survey(cr, uid, ids, context=context)
- return value
+ def action_print_survey(self, cr, uid, ids, context=None):
+ """ If response is available then print this response otherwise print survey form (print template of the survey) """
+ context = context if context else {}
+ applicant = self.browse(cr, uid, ids, context=context)[0]
+ survey_obj = self.pool.get('survey.survey')
+ response_obj = self.pool.get('survey.user_input')
+ if not applicant.response_id:
+ return survey_obj.action_print_survey(cr, uid, [applicant.survey.id], context=context)
+ else:
+ response = response_obj.browse(cr, uid, applicant.response_id.id, context=context)
+ context.update({'survey_token': response.token})
+ return survey_obj.action_print_survey(cr, uid, [applicant.survey.id], context=context)
def action_get_attachment_tree_view(self, cr, uid, ids, context=None):
model, action_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'action_attachment')
@@ -391,9 +401,9 @@ class hr_applicant(osv.Model):
ids = [ids]
res = True
- # user_id change: update date_start
+ # user_id change: update date_open
if vals.get('user_id'):
- vals['date_start'] = fields.datetime.now()
+ vals['date_open'] = fields.datetime.now()
# stage_id: track last stage before update
if 'stage_id' in vals:
vals['date_last_stage_update'] = fields.datetime.now()
@@ -518,7 +528,7 @@ class hr_job(osv.osv):
return res
_columns = {
- 'survey_id': fields.many2one('survey', 'Interview Form', help="Choose an interview form for this job position and you will be able to print/answer this interview from all applicants who apply for this job"),
+ 'survey_id': fields.many2one('survey.survey', 'Interview Form', help="Choose an interview form for this job position and you will be able to print/answer this interview from all applicants who apply for this job"),
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
help="Email alias for this job position. New emails will automatically "
"create new applicants for this job position."),
@@ -559,21 +569,9 @@ class hr_job(osv.osv):
return res
def action_print_survey(self, cr, uid, ids, context=None):
- if context is None:
- context = {}
- datas = {}
- record = self.browse(cr, uid, ids, context=context)[0]
- if record.survey_id:
- datas['ids'] = [record.survey_id.id]
- datas['model'] = 'survey.print'
- context.update({'response_id': [0], 'response_no': 0})
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'survey.form',
- 'datas': datas,
- 'context': context,
- 'nodestroy': True,
- }
+ job = self.browse(cr, uid, ids, context=context)[0]
+ survey_id = job.survey_id.id
+ return self.pool.get('survey.survey').action_print_survey(cr, uid, [survey_id], context=context)
def action_get_attachment_tree_view(self, cr, uid, ids, context=None):
#open attachments of job and related applicantions.
diff --git a/addons/hr_recruitment/hr_recruitment_data.xml b/addons/hr_recruitment/hr_recruitment_data.xml
index 8a88d8ebe5f..5849a67d949 100644
--- a/addons/hr_recruitment/hr_recruitment_data.xml
+++ b/addons/hr_recruitment/hr_recruitment_data.xml
@@ -118,379 +118,6 @@
-
- Job Survey
- 20
-
-
-
- 5
-
-
- Default Section
-
-
-
-
- Education & Activities
-
-
-
-
- Importance
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- From which university will you graduate?
-
- single_textbox
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Rate the Importance
-
- matrix_of_choices_only_one_ans
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Education
-
- comment
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Knowledge
-
- comment
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- What is your gender?
-
- multiple_choice_only_one_ans
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
-
- 1
- Male
-
-
-
-
-
- 1
- Female
-
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- What age group do you belong to?
-
- multiple_choice_only_one_ans
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
-
- 1
- 0 - 15
-
-
-
-
- 1
- 16 - 20
-
-
-
-
- 1
- 21 - 30
-
-
-
-
- 1
- 31 - 40
-
-
-
-
- 1
- 41 - 50
-
-
-
-
- 1
- 51 - 60
-
-
-
-
- 1
- 61 - 70
-
-
-
-
- 1
- 71 +
-
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Experience
-
- comment
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
- 1
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
- This question requires an answer.
-
- Activities
-
- comment
- The comment you entered is in an invalid format.
-
-
-
- Other
-
-
-
-
-
- Not important
-
-
-
-
-
- Somewhat important
-
-
-
-
-
- Important
-
-
-
-
-
- Very important
-
-
-
-
-
- Most important
-
-
-
-
- 1
- Good pay
-
-
-
-
- 1
- Getting on with colleagues
-
-
-
-
- 1
- Office environment (décor, light, space etc)
-
-
-
-
- 1
- Desk space
-
-
-
-
- 1
- State of the art technology
-
-
-
-
- 1
- Office location (proximity to home)
-
-
-
-
- 1
- Good management/boss
-
-
-
-
- 1
- Freebies such as tea, coffee and stationery
-
-
-
-
- 1
- Perks such as free parking, gym passes etc
-
-
-
-
- 1
- No out of hours working
-
-
-
-
- 1
- Dress code
-
-
-
-
- 1
- Regular meetings
-
-
-
-
- 1
- Good social life (office nights out, good Christmas parties etc)
-
-
-
-
jobs
diff --git a/addons/hr_recruitment/hr_recruitment_demo.xml b/addons/hr_recruitment/hr_recruitment_demo.xml
index 8ba49a2beb8..3d6c05c1489 100644
--- a/addons/hr_recruitment/hr_recruitment_demo.xml
+++ b/addons/hr_recruitment/hr_recruitment_demo.xml
@@ -126,35 +126,35 @@
recruit4
-
+
-
+
-
+ recruit1
-
+ 1recruit
-
+ recruit3
-
+ recruit6
-
+
-
+ -->
hr.applicant
diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml
index c9dc0d04ffb..53e35ea58d1 100644
--- a/addons/hr_recruitment/hr_recruitment_view.xml
+++ b/addons/hr_recruitment/hr_recruitment_view.xml
@@ -54,7 +54,7 @@
-
+
@@ -76,9 +76,9 @@
@@ -318,7 +318,7 @@
process and follow up all operations: meetings, interviews, etc.
Applicants and their attached CV are created automatically when an email is sent.
- If you install the document management modules, all resumes are indexed automatically,
+ If you install the document management modules, all resumes are indexed automatically,
so that you can easily search through their content.
- Click here to create a new job or remove the filter on "In Recruitment" to recruit for an on hold job.
+ Click here to create a new job or remove the filter on "In Recruitment" to recruit for an on hold job.
Define job position profile and manage recruitment in a context of a particular job: print interview survey, define number of expected new employees, and manage its recruitment pipe
diff --git a/addons/hr_recruitment/security/ir.model.access.csv b/addons/hr_recruitment/security/ir.model.access.csv
index 3cc92705a15..9cd9897a51b 100644
--- a/addons/hr_recruitment/security/ir.model.access.csv
+++ b/addons/hr_recruitment/security/ir.model.access.csv
@@ -4,7 +4,7 @@ access_hr_recruitment_report,hr.recruitment.report,model_hr_recruitment_report,b
access_hr_recruitment_stage_user,hr.recruitment.stage.user,model_hr_recruitment_stage,base.group_hr_user,1,1,1,1
access_hr_recruitment_degree,hr.recruitment.degree,model_hr_recruitment_degree,base.group_hr_user,1,1,1,1
access_res_partner_hr_user,res.partner.user,base.model_res_partner,base.group_hr_user,1,1,1,1
-access_survey_hr_user,survey.hr.user,survey.model_survey,base.group_hr_user,1,1,1,0
+access_survey_hr_user,survey.hr.user,survey.model_survey_survey,base.group_hr_user,1,1,1,0
access_calendar_event_hruser,calendar.event.hruser,calendar.model_calendar_event,base.group_hr_user,1,1,1,1
access_hr_recruitment_source_hr_officer,hr.recruitment.source,model_hr_recruitment_source,base.group_hr_user,1,1,1,1
access_hr_recruitment_source_all,hr.recruitment.source,model_hr_recruitment_source,,1,0,0,0
diff --git a/addons/hr_recruitment/static/src/js/job_position.js b/addons/hr_recruitment/static/src/js/job_position.js
index 06e880cb40d..43150117115 100644
--- a/addons/hr_recruitment/static/src/js/job_position.js
+++ b/addons/hr_recruitment/static/src/js/job_position.js
@@ -1,4 +1,5 @@
openerp.hr_recruitment = function (openerp) {
+ "use strict";
openerp.web_kanban.KanbanRecord.include({
on_card_clicked: function() {
@@ -10,4 +11,4 @@ openerp.hr_recruitment = function (openerp) {
},
});
-}
\ No newline at end of file
+};
diff --git a/addons/hr_recruitment/survey_data_recruitment.xml b/addons/hr_recruitment/survey_data_recruitment.xml
new file mode 100644
index 00000000000..f6aacb0f23c
--- /dev/null
+++ b/addons/hr_recruitment/survey_data_recruitment.xml
@@ -0,0 +1,230 @@
+
+
+
+
+
+ Recruitment Form
+
+ hr_recruitment
+
+
+ <p>This form is intended to help the responsible of a recruitment interview.</p>
+ <p></p>
+
+
+
+ Basic information
+
+ 1
+ <p></p>
+
+
+
+ 1
+ From which university will you graduate?
+ textbox
+
+
+
+ 2
+ What is your gender?
+ simple_choice
+ dropdown
+
+
+
+ 1
+ Male
+
+
+
+ 2
+ Female
+
+
+
+ 3
+ What age group do you belong to?
+ simple_choice
+ columns
+ 4
+
+
+
+ 1
+ 0-15
+
+
+
+ 2
+ 16-20
+
+
+
+ 3
+ 21-30
+
+
+
+
+ 4
+ 31-40
+
+
+
+ 5
+ 41-50
+
+
+
+ 6
+ 51-60
+
+
+
+ 7
+ 61-70
+
+
+
+ 8
+ 71+
+
+
+
+ Education and Activities
+
+ 2
+ <p></p>
+
+
+
+ 1
+ Knowledge
+ free_text
+
+
+
+ 2
+ Education
+ free_text
+
+
+
+ 3
+ Experience
+ free_text
+
+
+
+ 4
+ Activities
+ free_text
+
+
+
+ Importance
+
+ 3
+ <p></p>
+
+
+
+ 1
+ Rate the Importance
+ matrix
+ simple
+
+
+
+ 1
+ Not important
+
+
+
+ 2
+ Somewhat important
+
+
+
+ 3
+ Important
+
+
+
+ 4
+ Very important
+
+
+
+ 5
+ Most important
+
+
+
+
+ 1
+ Good pay
+
+
+
+ 2
+ Getting on with colleagues
+
+
+
+ 3
+ Office environment
+
+
+
+ 4
+ Desk space
+
+
+
+ 5
+ State of the art technology
+
+
+
+ 6
+ Office location
+
+
+
+ 7
+ Good management
+
+
+
+ 8
+ Freebies such as tea, coffee and stationery
+
+
+
+ 9
+ Perks such as free parking, gym passes
+
+
+
+ 10
+ No out of hours working
+
+
+
+ 11
+ Dress code
+
+
+
+ 12
+ Regular meetings
+
+
+
+ 13
+ Good social life
+
+
+
diff --git a/addons/hr_recruitment/test/recruitment_process.yml b/addons/hr_recruitment/test/recruitment_process.yml
index 8588e5c96e8..85abad2a9d6 100644
--- a/addons/hr_recruitment/test/recruitment_process.yml
+++ b/addons/hr_recruitment/test/recruitment_process.yml
@@ -47,16 +47,6 @@
-
!python {model: hr.applicant}: |
self.action_makeMeeting(cr, uid, [ref('hr_case_programmer')])
--
- Applicant fillup the answer of the interview quetion.
--
- !python {model: survey.question.wiz}: |
- ctx = context.copy()
- ctx.update({'active_model': 'hr.applicant', 'active_id': ref("hr_case_programmer"), 'active_ids': [ref("hr_case_programmer")], 'survey_id': ref("survey_job_0")})
- self.fields_view_get(cr, uid, ref("survey.view_survey_question_message"),"form", context=ctx)
- vals = self.default_get(cr, uid , [], context=ctx)
- self.create(cr, uid, vals, context=ctx)
- self.action_new_page(cr, uid, [ref("survey_job_0")], context=ctx)
-
I print Applicant fill up the interview quetion
-
diff --git a/addons/survey/__init__.py b/addons/survey/__init__.py
index 065d64a87e2..0f961ebd110 100644
--- a/addons/survey/__init__.py
+++ b/addons/survey/__init__.py
@@ -20,7 +20,5 @@
##############################################################################
import survey
+import controllers
import wizard
-import report
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/survey/__openerp__.py b/addons/survey/__openerp__.py
index d5e4c3af10c..72b11b0d78b 100644
--- a/addons/survey/__openerp__.py
+++ b/addons/survey/__openerp__.py
@@ -21,44 +21,39 @@
{
'name': 'Survey',
- 'version': '1.0',
- 'category': 'Tools',
+ 'version': '2.0',
+ 'category': 'Marketing',
'description': """
-This module is used for surveying.
-==================================
+Create beautiful web surveys and visualize answers
+==================================================
It depends on the answers or reviews of some questions by different users. A
-survey may have multiple pages. Each page may contain multiple questions and each
-question may have multiple answers. Different users may give different answers of
-question and according to that survey is done. Partners are also sent mails with
-user name and password for the invitation of the survey.
+survey may have multiple pages. Each page may contain multiple questions and
+each question may have multiple answers. Different users may give different
+answers of question and according to that survey is done. Partners are also
+sent mails with personal token for the invitation of the survey.
""",
+ 'summary': 'Create surveys, collect answers and print statistics',
'author': 'OpenERP SA',
- 'depends': ['mail'],
+ 'website': 'https://www.openerp.com/apps/survey/',
+ 'depends': ['email_template', 'mail', 'website', 'marketing'],
'data': [
- 'survey_report.xml',
- 'survey_data.xml',
- 'wizard/survey_selection.xml',
- 'wizard/survey_answer.xml',
'security/survey_security.xml',
'security/ir.model.access.csv',
- 'survey_view.xml',
- 'wizard/survey_print_statistics.xml',
- 'wizard/survey_print_answer.xml',
- 'wizard/survey_browse_answer.xml',
- 'wizard/survey_print.xml',
- 'wizard/survey_send_invitation.xml'
- ],
- 'demo': ['survey_demo.xml'],
- 'test': [
- 'test/draft2open2close_survey.yml',
- 'test/draft2open2close_request.yml',
- 'test/survey_question_type.yml',
- 'test/survey_report.yml',
+ 'views/survey_views.xml',
+ 'views/survey_templates.xml',
+ 'views/survey_result.xml',
+ 'wizard/survey_email_compose_message.xml',
+ 'data/survey_stages.xml',
+ 'data/survey_cron.xml'
],
+ 'demo': ['data/survey_demo_user.xml',
+ 'data/survey_demo_feedback.xml',
+ 'data/survey.user_input.csv',
+ 'data/survey.user_input_line.csv'],
'installable': True,
'auto_install': False,
- 'images': ['images/survey_answers.jpeg','images/survey_pages.jpeg','images/surveys.jpeg'],
- 'css': ['static/src/css/survey.css','static/css/survey.css'],
+ 'application': True,
+ 'sequence': 10,
+ 'images': [],
}
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/survey/report/__init__.py b/addons/survey/controllers/__init__.py
similarity index 68%
rename from addons/survey/report/__init__.py
rename to addons/survey/controllers/__init__.py
index 26fc1d46d63..672df6ec1f9 100644
--- a/addons/survey/report/__init__.py
+++ b/addons/survey/controllers/__init__.py
@@ -2,13 +2,12 @@
##############################################################################
#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2009 Tiny SPRL (). All Rights Reserved
-# $Id$
+# Copyright (C) 2004-TODAY OpenERP S.A.
#
# 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.
+# 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
@@ -20,8 +19,4 @@
#
##############################################################################
-import survey_analysis_report
-import survey_form
-import survey_browse_response
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+import main
diff --git a/addons/survey/controllers/main.py b/addons/survey/controllers/main.py
new file mode 100644
index 00000000000..a937cd0e826
--- /dev/null
+++ b/addons/survey/controllers/main.py
@@ -0,0 +1,356 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2013-Today OpenERP SA ().
+#
+# 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 .
+#
+##############################################################################
+
+import json
+import logging
+import werkzeug
+from datetime import datetime
+from math import ceil
+
+from openerp import SUPERUSER_ID
+from openerp.addons.web import http
+from openerp.addons.web.http import request
+from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT as DTF
+from openerp.tools.safe_eval import safe_eval
+
+
+_logger = logging.getLogger(__name__)
+
+
+class WebsiteSurvey(http.Controller):
+
+ ## HELPER METHODS ##
+
+ def _check_bad_cases(self, cr, uid, request, survey_obj, survey, user_input_obj, context=None):
+ # In case of bad survey, redirect to surveys list
+ if survey_obj.exists(cr, SUPERUSER_ID, 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(cr, uid, context):
+ return request.website.render("website.403")
+
+ # In case of non open surveys
+ if survey.stage_id.closed:
+ return request.website.render("survey.notopen")
+
+ # If there is no pages
+ if not survey.page_ids:
+ return request.website.render("survey.nopages")
+
+ # Everything seems to be ok
+ return None
+
+ def _check_deadline(self, cr, uid, user_input, context=None):
+ '''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:
+ dt_deadline = datetime.strptime(user_input.deadline, DTF)
+ dt_now = datetime.now()
+ if dt_now > dt_deadline: # survey is not open anymore
+ return request.website.render("survey.notopen")
+
+ return None
+
+ ## ROUTES HANDLERS ##
+
+ # Survey start
+ @http.route(['/survey/start/',
+ '/survey/start//'],
+ type='http', auth='public', multilang=True, website=True)
+ 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']
+
+ # Test mode
+ if token and token == "phantom":
+ _logger.info("[survey] Phantom mode")
+ user_input_id = user_input_obj.create(cr, uid, {'survey_id': survey.id, 'test_entry': True}, context=context)
+ user_input = user_input_obj.browse(cr, uid, [user_input_id], context=context)[0]
+ data = {'survey': survey, 'page': None, 'token': user_input.token}
+ return request.website.render('survey.survey_init', data)
+ # END Test mode
+
+ # Controls if the survey can be displayed
+ errpage = self._check_bad_cases(cr, uid, request, survey_obj, survey, user_input_obj, context=context)
+ if errpage:
+ return errpage
+
+ # Manual surveying
+ if not token:
+ user_input_id = user_input_obj.create(cr, uid, {'survey_id': survey.id}, context=context)
+ user_input = user_input_obj.browse(cr, uid, [user_input_id], context=context)[0]
+ else:
+ try:
+ user_input_id = user_input_obj.search(cr, uid, [('token', '=', token)], context=context)[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]
+
+ # Do not open expired survey
+ errpage = self._check_deadline(cr, uid, user_input, context=context)
+ if errpage:
+ return errpage
+
+ # 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))
+
+ # Survey displaying
+ @http.route(['/survey/fill//',
+ '/survey/fill///'],
+ type='http', auth='public', multilang=True, website=True)
+ def fill_survey(self, survey, token, prev=None, **post):
+ '''Display and validates a survey'''
+ cr, uid, context = request.cr, request.uid, request.context
+ survey_obj = request.registry['survey.survey']
+ user_input_obj = request.registry['survey.user_input']
+
+ # Controls if the survey can be displayed
+ errpage = self._check_bad_cases(cr, uid, request, survey_obj, survey, user_input_obj, context=context)
+ if errpage:
+ return errpage
+
+ # Load the user_input
+ 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]
+
+ # Do not display expired survey (even if some pages have already been
+ # displayed -- There's a time for everything!)
+ errpage = self._check_deadline(cr, uid, user_input, context=context)
+ if errpage:
+ return errpage
+
+ # Select the right page
+ if user_input.state == 'new': # First page
+ page, page_nr, last = survey_obj.next_page(cr, uid, user_input, 0, go_back=False, context=context)
+ 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
+ return request.website.render('survey.sfinished', {'survey': survey,
+ 'token': token,
+ 'user_input': user_input})
+ elif user_input.state == 'skip':
+ flag = (True if prev and prev == 'prev' else False)
+ page, page_nr, last = survey_obj.next_page(cr, uid, user_input, user_input.last_displayed_page_id.id, go_back=flag, context=context)
+ 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)
+ else:
+ return request.website.render("website.403")
+
+ # AJAX prefilling of a survey
+ @http.route(['/survey/prefill//',
+ '/survey/prefill///'],
+ type='http', auth='public', multilang=True, website=True)
+ def prefill(self, survey, token, page=None, **post):
+ cr, uid, context = request.cr, request.uid, request.context
+ user_input_line_obj = request.registry['survey.user_input_line']
+ ret = {}
+
+ # Fetch previous answers
+ if page:
+ ids = user_input_line_obj.search(cr, uid, [('user_input_id.token', '=', token), ('page_id', '=', page.id)], context=context)
+ else:
+ ids = user_input_line_obj.search(cr, uid, [('user_input_id.token', '=', token)], context=context)
+ previous_answers = user_input_line_obj.browse(cr, uid, ids, context=context)
+
+ # Return non empty answers in a JSON compatible format
+ for answer in previous_answers:
+ if not answer.skipped:
+ answer_tag = '%s_%s_%s' % (answer.survey_id.id, answer.page_id.id, answer.question_id.id)
+ answer_value = None
+ if answer.answer_type == 'free_text':
+ answer_value = answer.value_free_text
+ elif answer.answer_type == 'text' and answer.question_id.type == 'textbox':
+ answer_value = answer.value_text
+ elif answer.answer_type == 'text' and answer.question_id.type != 'textbox':
+ # here come comment answers for matrices, simple choice and multiple choice
+ answer_tag = "%s_%s" % (answer_tag, 'comment')
+ answer_value = answer.value_text
+ elif answer.answer_type == 'number':
+ answer_value = answer.value_number.__str__()
+ elif answer.answer_type == 'date':
+ answer_value = answer.value_date
+ elif answer.answer_type == 'suggestion' and not answer.value_suggested_row:
+ answer_value = answer.value_suggested.id
+ elif answer.answer_type == 'suggestion' and answer.value_suggested_row:
+ answer_tag = "%s_%s" % (answer_tag, answer.value_suggested_row.id)
+ answer_value = answer.value_suggested.id
+ if answer_value:
+ dict_soft_update(ret, answer_tag, answer_value)
+ else:
+ _logger.warning("[survey] No answer has been found for question %s marked as non skipped" % answer_tag)
+ return json.dumps(ret)
+
+ # AJAX submission of a page
+ @http.route(['/survey/submit/'],
+ type='http', auth='public', multilang=True, website=True)
+ def submit(self, survey, **post):
+ _logger.debug('Incoming data: %s', post)
+ page_id = int(post['page_id'])
+ cr, uid, context = request.cr, request.uid, request.context
+ survey_obj = request.registry['survey.survey']
+ 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)
+
+ # Answer validation
+ errors = {}
+ for question in questions:
+ answer_tag = "%s_%s_%s" % (survey.id, page_id, question.id)
+ errors.update(questions_obj.validate_question(cr, uid, question, post, answer_tag, context=context))
+
+ ret = {}
+ if (len(errors) != 0):
+ # Return errors messages to webpage
+ ret['errors'] = errors
+ 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")
+ for question in questions:
+ answer_tag = "%s_%s_%s" % (survey.id, page_id, question.id)
+ user_input_line_obj.save_lines(cr, uid, user_input_id, question, post, answer_tag, context=context)
+
+ user_input = user_input_obj.browse(cr, uid, user_input_id, context=context)
+ go_back = post['button_submit'] == 'previous'
+ next_page, _, last = survey_obj.next_page(cr, uid, user_input, page_id, go_back=go_back, context=context)
+ vals = {'last_displayed_page_id': page_id}
+ if next_page is None and not go_back:
+ vals.update({'state': 'done'})
+ else:
+ vals.update({'state': 'skip'})
+ user_input_obj.write(cr, uid, user_input_id, vals, context=context)
+ ret['redirect'] = '/survey/fill/%s/%s' % (survey.id, post['token'])
+ if go_back:
+ ret['redirect'] += '/prev'
+ return json.dumps(ret)
+
+ # Printing routes
+ @http.route(['/survey/print/',
+ '/survey/print//'],
+ type='http', auth='user', multilang=True, website=True)
+ def print_survey(self, survey, token=None, **post):
+ '''Display an survey in printable view; if is set, it will
+ grab the answers of the user_input_id that has .'''
+ return request.website.render('survey.survey_print',
+ {'survey': survey,
+ 'token': token,
+ 'page_nr': 0})
+
+ @http.route(['/survey/results/'],
+ type='http', auth='user', multilang=True, website=True)
+ def survey_reporting(self, survey, token=None, **post):
+ '''Display survey Results & Statistics for given survey.'''
+ result_template, current_filters, filter_display_data, filter_finish = 'survey.result', [], [], False
+ survey_obj = request.registry['survey.survey']
+ if not survey.user_input_ids or not [input_id.id for input_id in survey.user_input_ids if input_id.state != 'new']:
+ result_template = 'survey.no_result'
+ if 'finished' in post:
+ post.pop('finished')
+ filter_finish = True
+ if post or filter_finish:
+ filter_data = self.get_filter_data(post)
+ current_filters = survey_obj.filter_input_ids(request.cr, request.uid, filter_data, filter_finish, context=request.context)
+ filter_display_data = survey_obj.get_filter_display_data(request.cr, request.uid, filter_data, context=request.context)
+ return request.website.render(result_template,
+ {'survey_dict': self.prepare_result_dict(survey, current_filters),
+ 'page_range': self.page_range,
+ 'current_filters': current_filters,
+ 'filter_display_data': filter_display_data,
+ 'filter_finish': filter_finish
+ })
+
+ 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':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), 'graph_data': self.get_graph_data(question, current_filters)}
+ 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 = []
+ for ids in post:
+ #if user add some random data in query URI, ignore it
+ try:
+ row_id, answer_id = ids.split(',')
+ filters.append({'row_id': int(row_id), 'answer_id': int(answer_id)})
+ except:
+ return filters
+ return filters
+
+ def page_range(self, total_record, limit):
+ '''Returns number of pages required for pagination'''
+ total = ceil(total_record / float(limit))
+ return range(1, int(total + 1))
+
+ def get_graph_data(self, question, current_filters=[]):
+ '''Returns formatted data required by graph library on basis of filter'''
+ survey_obj = request.registry['survey.survey']
+ result = []
+ if question.type == 'multiple_choice':
+ result.append({'key': str(question.question),
+ 'values': survey_obj.prepare_result(request.cr, request.uid, question, current_filters, context=request.context)})
+ if question.type == 'simple_choice':
+ result = survey_obj.prepare_result(request.cr, request.uid, question, current_filters, context=request.context)
+ if question.type == 'matrix':
+ 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']:
+ if res[1] == answer:
+ values.append({'text': data['rows'][res[0]], 'count': data['result'][res]})
+ result.append({'key': data['answers'].get(answer), 'values': values})
+ return json.dumps(result)
+
+def dict_soft_update(dictionary, key, value):
+ ''' Insert the pair : into the . If is
+ already present, this function will append to the list of
+ existing data (instead of erasing it) '''
+ if key in dictionary:
+ dictionary[key].append(value)
+ else:
+ dictionary.update({key: [value]})
diff --git a/addons/survey/data/survey.user_input.csv b/addons/survey/data/survey.user_input.csv
new file mode 100644
index 00000000000..7af2096bb88
--- /dev/null
+++ b/addons/survey/data/survey.user_input.csv
@@ -0,0 +1,7 @@
+id,survey_id:id,state
+ui1,feedback_form,done
+ui2,feedback_form,done
+ui3,feedback_form,done
+ui4,feedback_form,skip
+ui5,feedback_form,skip
+ui6,feedback_form,new
diff --git a/addons/survey/data/survey.user_input_line.csv b/addons/survey/data/survey.user_input_line.csv
new file mode 100644
index 00000000000..58b67969d5a
--- /dev/null
+++ b/addons/survey/data/survey.user_input_line.csv
@@ -0,0 +1,125 @@
+id,user_input_id:id,question_id:id,skipped,answer_type,value_text,value_number,value_date,value_free_text,value_suggested:id,value_suggested_row:id
+uil_1,ui1,feedback_1_1,,suggestion,,,,,choice_1_1_1,
+uil_2,ui1,feedback_1_2,,suggestion,,,,,choice_1_2_2,
+uil_3,ui1,feedback_2_1,,suggestion,,,,,fcol_2_1_2,frow_2_1_1
+uil_4,ui1,feedback_2_1,,suggestion,,,,,fcol_2_1_3,frow_2_1_2
+uil_5,ui1,feedback_2_1,,suggestion,,,,,fcol_2_1_4,frow_2_1_3
+uil_6,ui1,feedback_2_1,,suggestion,,,,,fcol_2_1_1,frow_2_1_4
+uil_7,ui1,feedback_2_1,,suggestion,,,,,fcol_2_1_2,frow_2_1_5
+uil_8,ui1,feedback_2_2,,suggestion,,,,,fcol_2_2_4,frow_2_2_1
+uil_9,ui1,feedback_2_2,,suggestion,,,,,fcol_2_2_1,frow_2_2_2
+uil_10,ui1,feedback_2_2,,suggestion,,,,,fcol_2_2_2,frow_2_2_3
+uil_11,ui1,feedback_2_2,,suggestion,,,,,fcol_2_2_3,frow_2_2_4
+uil_12,ui1,feedback_2_2,,suggestion,,,,,fcol_2_2_4,frow_2_2_5
+uil_13,ui1,feedback_2_3,,free_text,,,,It is very difficult to understand,,
+uil_14,ui1,feedback_2_4,,suggestion,,,,,choice_2_4_1,
+uil_15,ui1,feedback_2_4,,suggestion,,,,,choice_2_4_2,
+uil_16,ui1,feedback_2_5,,suggestion,,,,,fcol_2_5_3,frow_2_5_1
+uil_17,ui1,feedback_2_5,,suggestion,,,,,fcol_2_5_4,frow_2_5_2
+uil_18,ui1,feedback_2_5,,suggestion,,,,,fcol_2_5_1,frow_2_5_3
+uil_19,ui1,feedback_2_5,,suggestion,,,,,fcol_2_5_2,frow_2_5_4
+uil_20,ui1,feedback_2_5,,suggestion,,,,,fcol_2_5_3,frow_2_5_5
+uil_21,ui1,feedback_2_6,,suggestion,,,,,choice_2_6_2,
+uil_22,ui1,feedback_2_7,,suggestion,,,,,fcol_2_7_2,frow_2_7_1
+uil_23,ui1,feedback_2_7,,suggestion,,,,,fcol_2_7_3,frow_2_7_2
+uil_24,ui1,feedback_2_7,,suggestion,,,,,fcol_2_7_4,frow_2_7_3
+uil_25,ui1,feedback_2_7,,suggestion,,,,,fcol_2_7_1,frow_2_7_4
+uil_26,ui1,feedback_3_1,,suggestion,,,,,choice_3_1_1,
+uil_27,ui1,feedback_3_1,,suggestion,,,,,choice_3_1_5,
+uil_28,ui1,feedback_3_2,,free_text,,,,Accept merge proposals more quickly,,
+uil_29,ui1,feedback_3_3,,free_text,,,,Pay them!,,
+uil_30,ui1,feedback_4_1,,suggestion,,,,,choice_4_1_2,
+uil_31,ui1,feedback_4_1,,suggestion,,,,,choice_4_1_3,
+uil_32,ui1,feedback_4_1,,suggestion,,,,,choice_4_1_4,
+uil_33,ui2,feedback_1_1,,suggestion,,,,,choice_1_1_3,
+uil_34,ui2,feedback_1_2,,suggestion,,,,,choice_1_2_3,
+uil_35,ui2,feedback_2_1,,suggestion,,,,,fcol_2_1_3,frow_2_1_1
+uil_36,ui2,feedback_2_1,,suggestion,,,,,fcol_2_1_4,frow_2_1_2
+uil_37,ui2,feedback_2_1,,suggestion,,,,,fcol_2_1_1,frow_2_1_3
+uil_38,ui2,feedback_2_1,,suggestion,,,,,fcol_2_1_2,frow_2_1_4
+uil_39,ui2,feedback_2_1,,suggestion,,,,,fcol_2_1_3,frow_2_1_5
+uil_40,ui2,feedback_2_2,,suggestion,,,,,fcol_2_2_3,frow_2_2_1
+uil_41,ui2,feedback_2_2,,suggestion,,,,,fcol_2_2_4,frow_2_2_2
+uil_42,ui2,feedback_2_2,,suggestion,,,,,fcol_2_2_1,frow_2_2_3
+uil_43,ui2,feedback_2_2,,suggestion,,,,,fcol_2_2_2,frow_2_2_4
+uil_44,ui2,feedback_2_2,,suggestion,,,,,fcol_2_2_3,frow_2_2_5
+uil_45,ui2,feedback_2_3,,free_text,,,,I prefer a command-line tool,,
+uil_46,ui2,feedback_2_4,,suggestion,,,,,choice_2_4_3,
+uil_47,ui2,feedback_2_4,,suggestion,,,,,choice_2_4_1,
+uil_48,ui2,feedback_2_5,,suggestion,,,,,fcol_2_5_4,frow_2_5_1
+uil_49,ui2,feedback_2_5,,suggestion,,,,,fcol_2_5_1,frow_2_5_2
+uil_50,ui2,feedback_2_5,,suggestion,,,,,fcol_2_5_2,frow_2_5_3
+uil_51,ui2,feedback_2_5,,suggestion,,,,,fcol_2_5_3,frow_2_5_4
+uil_52,ui2,feedback_2_5,,suggestion,,,,,fcol_2_5_4,frow_2_5_5
+uil_53,ui2,feedback_2_6,,suggestion,,,,,choice_2_6_1,
+uil_54,ui2,feedback_2_7,,suggestion,,,,,fcol_2_7_3,frow_2_7_1
+uil_55,ui2,feedback_2_7,,suggestion,,,,,fcol_2_7_4,frow_2_7_2
+uil_56,ui2,feedback_2_7,,suggestion,,,,,fcol_2_7_1,frow_2_7_3
+uil_57,ui2,feedback_2_7,,suggestion,,,,,fcol_2_7_2,frow_2_7_4
+uil_58,ui2,feedback_3_1,,suggestion,,,,,choice_3_1_2,
+uil_59,ui2,feedback_3_1,,suggestion,,,,,choice_3_1_3,
+uil_60,ui2,feedback_3_1,,suggestion,,,,,choice_3_1_4,
+uil_61,ui2,feedback_3_2,,free_text,,,,Reward most engaged contributors,,
+uil_62,ui2,feedback_3_3,,free_text,,,,Launch OpenERP hackhatons,,
+uil_63,ui2,feedback_4_1,,suggestion,,,,,choice_4_1_1,
+uil_64,ui2,feedback_4_1,,suggestion,,,,,choice_4_1_2,
+uil_65,ui2,feedback_4_1,,suggestion,,,,,choice_4_1_3,
+uil_66,ui3,feedback_1_1,,suggestion,,,,,choice_1_1_1,
+uil_67,ui3,feedback_1_2,,suggestion,,,,,choice_1_2_2,
+uil_68,ui3,feedback_2_1,,suggestion,,,,,fcol_2_1_2,frow_2_1_1
+uil_69,ui3,feedback_2_1,,suggestion,,,,,fcol_2_1_3,frow_2_1_2
+uil_70,ui3,feedback_2_1,,suggestion,,,,,fcol_2_1_4,frow_2_1_3
+uil_71,ui3,feedback_2_1,,suggestion,,,,,fcol_2_1_1,frow_2_1_4
+uil_72,ui3,feedback_2_1,,suggestion,,,,,fcol_2_1_2,frow_2_1_5
+uil_73,ui3,feedback_2_2,,suggestion,,,,,fcol_2_2_4,frow_2_2_1
+uil_74,ui3,feedback_2_2,,suggestion,,,,,fcol_2_2_1,frow_2_2_2
+uil_75,ui3,feedback_2_2,,suggestion,,,,,fcol_2_2_2,frow_2_2_3
+uil_76,ui3,feedback_2_2,,suggestion,,,,,fcol_2_2_3,frow_2_2_4
+uil_77,ui3,feedback_2_2,,suggestion,,,,,fcol_2_2_4,frow_2_2_5
+uil_78,ui3,feedback_2_3,,free_text,,,,I prefer a command-line tool,,
+uil_79,ui3,feedback_2_4,,suggestion,,,,,choice_2_4_1,
+uil_80,ui3,feedback_2_4,,suggestion,,,,,choice_2_4_2,
+uil_81,ui3,feedback_2_5,,suggestion,,,,,fcol_2_5_3,frow_2_5_1
+uil_82,ui3,feedback_2_5,,suggestion,,,,,fcol_2_5_4,frow_2_5_2
+uil_83,ui3,feedback_2_5,,suggestion,,,,,fcol_2_5_1,frow_2_5_3
+uil_84,ui3,feedback_2_5,,suggestion,,,,,fcol_2_5_2,frow_2_5_4
+uil_85,ui3,feedback_2_5,,suggestion,,,,,fcol_2_5_3,frow_2_5_5
+uil_86,ui3,feedback_2_6,,suggestion,,,,,choice_2_6_2,
+uil_87,ui3,feedback_2_7,,suggestion,,,,,fcol_2_7_2,frow_2_7_1
+uil_88,ui3,feedback_2_7,,suggestion,,,,,fcol_2_7_3,frow_2_7_2
+uil_89,ui3,feedback_2_7,,suggestion,,,,,fcol_2_7_4,frow_2_7_3
+uil_90,ui3,feedback_2_7,,suggestion,,,,,fcol_2_7_1,frow_2_7_4
+uil_91,ui3,feedback_3_1,,suggestion,,,,,choice_3_1_1,
+uil_92,ui3,feedback_3_1,,suggestion,,,,,choice_3_1_5,
+uil_93,ui3,feedback_3_2,,free_text,,,,Reward most engaged contributors,,
+uil_94,ui3,feedback_3_3,,free_text,,,,Launch OpenERP hackhatons,,
+uil_95,ui3,feedback_4_1,,suggestion,,,,,choice_4_1_2,
+uil_96,ui3,feedback_4_1,,suggestion,,,,,choice_4_1_3,
+uil_97,ui3,feedback_4_1,,suggestion,,,,,choice_4_1_4,
+uil_98,ui4,feedback_1_1,,suggestion,,,,,choice_1_1_2,
+uil_99,ui4,feedback_1_2,,suggestion,,,,,choice_1_2_3,
+uil_100,ui4,feedback_2_1,,suggestion,,,,,fcol_2_1_1,frow_2_1_1
+uil_101,ui4,feedback_2_1,,suggestion,,,,,fcol_2_1_2,frow_2_1_2
+uil_102,ui4,feedback_2_1,,suggestion,,,,,fcol_2_1_3,frow_2_1_3
+uil_103,ui4,feedback_2_1,,suggestion,,,,,fcol_2_1_4,frow_2_1_4
+uil_104,ui4,feedback_2_1,,suggestion,,,,,fcol_2_1_1,frow_2_1_5
+uil_105,ui4,feedback_2_2,,suggestion,,,,,fcol_2_2_4,frow_2_2_1
+uil_106,ui4,feedback_2_2,,suggestion,,,,,fcol_2_2_1,frow_2_2_2
+uil_107,ui4,feedback_2_2,,suggestion,,,,,fcol_2_2_2,frow_2_2_3
+uil_108,ui4,feedback_2_2,,suggestion,,,,,fcol_2_2_3,frow_2_2_4
+uil_109,ui4,feedback_2_2,,suggestion,,,,,fcol_2_2_4,frow_2_2_5
+uil_110,ui4,feedback_2_3,,free_text,,,,A more graphical tool would be useful.,,
+uil_111,ui4,feedback_2_4,,suggestion,,,,,choice_2_4_2,
+uil_112,ui4,feedback_2_4,,suggestion,,,,,choice_2_4_3,
+uil_113,ui4,feedback_2_5,,suggestion,,,,,fcol_2_5_3,frow_2_5_1
+uil_114,ui4,feedback_2_5,,suggestion,,,,,fcol_2_5_4,frow_2_5_2
+uil_115,ui4,feedback_2_5,,suggestion,,,,,fcol_2_5_1,frow_2_5_3
+uil_116,ui4,feedback_2_5,,suggestion,,,,,fcol_2_5_2,frow_2_5_4
+uil_117,ui4,feedback_2_5,,suggestion,,,,,fcol_2_5_3,frow_2_5_5
+uil_118,ui4,feedback_2_6,,suggestion,,,,,choice_2_6_1,
+uil_119,ui4,feedback_2_7,,suggestion,,,,,fcol_2_7_2,frow_2_7_1
+uil_120,ui4,feedback_2_7,,suggestion,,,,,fcol_2_7_3,frow_2_7_2
+uil_121,ui4,feedback_2_7,,suggestion,,,,,fcol_2_7_4,frow_2_7_3
+uil_122,ui4,feedback_2_7,,suggestion,,,,,fcol_2_7_1,frow_2_7_4
+uil_123,ui5,feedback_1_1,,suggestion,,,,,choice_1_1_1,
+uil_124,ui5,feedback_1_2,,suggestion,,,,,choice_1_2_2,
diff --git a/addons/survey/data/survey_cron.xml b/addons/survey/data/survey_cron.xml
new file mode 100644
index 00000000000..7f22bbcb5ff
--- /dev/null
+++ b/addons/survey/data/survey_cron.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+ Run Clean empty surveys
+
+
+ 1
+ hours
+ -1
+
+
+
+
+
+
+
diff --git a/addons/survey/data/survey_demo_feedback.xml b/addons/survey/data/survey_demo_feedback.xml
new file mode 100644
index 00000000000..7b59bde24e4
--- /dev/null
+++ b/addons/survey/data/survey_demo_feedback.xml
@@ -0,0 +1,441 @@
+
+
+
+
+
+ User Feedback Form
+
+
+
+ <p>This survey should take less than five minutes.</p>
+ <p></p>
+
+
+
+ About your OpenERP usage
+
+ 1
+ <p></p>
+
+
+
+ 1
+ Are you using OpenERP on a daily basis?
+ simple_choice
+ dropdown
+
+
+
+
+ 1
+ Yes, I use a version < 7.0
+
+
+
+ 2
+ Yes, I use the 7.0 version, installed locally
+
+
+
+ 3
+ Yes, I use the online version of OpenERP
+
+
+
+ 4
+ No, I just tested it
+
+
+
+ 2
+ Which modules are you using/testing?
+ multiple_choice
+ 4
+
+
+
+
+ 1
+ Sales Management
+
+
+
+ 2
+ Purchases Management
+
+
+
+ 3
+ Financial Management
+
+
+
+ 4
+ CRM
+
+
+
+ 5
+ Project Management
+
+
+
+ 6
+ Human Ressources
+
+
+
+ Ergonomy and ease of use
+
+ 2
+ <p>These questions relate to the ergonomy and ease of use of OpenERP. Try to remind your firsts days on OpenERP and
+what have been your difficulties.</p>
+
+
+
+ 1
+ What do you think about the documentation available on doc.openerp.com?
+ matrix
+ simple
+
+
+
+
+ 1
+ Totally disagree
+
+
+
+ 2
+ Disagree
+
+
+
+ 3
+ Agree
+
+
+
+ 4
+ Totally agree
+
+
+
+ 1
+ It is up-to-date
+
+
+
+ 2
+ It helps in the beginning
+
+
+
+ 3
+ I use the contextual help in OpenERP
+
+
+
+ 4
+ It is complete
+
+
+
+ 5
+ It is clear
+
+
+
+ 2
+ What do you think about the process views of OpenERP, available in the web client ?
+ matrix
+ simple
+
+
+
+
+ 1
+ Totally disagree
+
+
+
+ 2
+ Disagree
+
+
+
+ 3
+ Agree
+
+
+
+ 4
+ Totally agree
+
+
+
+ 1
+ They help new users to understand OpenERP
+
+
+
+ 2
+ They are clean and correct
+
+
+
+ 3
+ They are useful on a daily usage
+
+
+
+ 4
+ A process is defined for all enterprise flows
+
+
+
+ 5
+ It's easy to find the process you need
+
+
+
+ 3
+ Do you have suggestions on how to improve the process view ?
+ free_text
+
+
+
+ 4
+ What do you think about the structure of the menus?
+ multiple_choice
+ 4
+
+
+
+
+ 1
+ The current menu structure is good
+
+
+
+ 2
+ It can be improved
+
+
+
+ 3
+ There are too much menus, it's complex to understand
+
+
+
+ 5
+ What do you think about the groups of users?
+ matrix
+ simple
+
+
+
+
+ 1
+ Totally disagree
+
+
+
+ 2
+ Disagree
+
+
+
+ 3
+ Agree
+
+
+
+ 4
+ Totally agree
+
+
+
+ 1
+ The security rules defined on groups are useful
+
+
+
+ 2
+ Those security rules are standard and can be used out-of-the-box in most cases
+
+
+
+ 3
+ The 'Usability/Extended View' group helps in daily work
+
+
+
+ 4
+ The 'Usability/Extended View' group hides only optional fields
+
+
+
+ 5
+ The groups set on menu items are relevant
+
+
+
+ 6
+ What do you think about the structure of the menus?
+ simple_choice
+ columns
+ 4
+
+
+
+
+ 1
+ There are too many groups defined, security is too complex to set
+
+
+
+ 2
+ There are too few groups defined, security isn't accurate enough
+
+
+
+ 3
+ The number of groups is good
+
+
+
+ 7
+ What do you think about configuration wizards?
+ matrix
+ simple
+
+
+
+
+ 1
+ Totally disagree
+
+
+
+ 2
+ Disagree
+
+
+
+ 3
+ Agree
+
+
+
+ 4
+ Totally agree
+
+
+
+ 1
+ Descriptions and help tooltips are clear enough
+
+
+
+ 2
+ Configuration wizard exists for each important setting
+
+
+
+ 3
+ Extra modules proposed are relevant
+
+
+
+ 4
+ Running the configuration wizards is a good way to spare time
+
+
+
+ Community and contributors
+
+ 3
+ <p></p>
+
+
+
+ 1
+ How do you contribute or plan to contribute to OpenERP?
+ multiple_choice
+ 6
+
+
+
+
+ 1
+ I participate to discussion and forums
+
+
+
+ 2
+ I'd like to contribute but I don't know how?
+
+
+
+ 3
+ I develop new features
+
+
+
+ 4
+ I help to translate
+
+
+
+ 5
+ I write documentations
+
+
+
+ 2
+ Do you have a proposition to help people to contribute?
+ free_text
+
+
+
+ 3
+ Do you have a proposition to attract new contributors?
+ free_text
+
+
+
+ Questions for developers
+
+ 4
+ <p>If you do not contribute or develop in OpenERP, skip this page.</p>
+
+
+
+ 1
+ Where do you develop your new features?
+ multiple_choice
+ 6
+
+
+
+ 1
+ I use Launchpad, like all official OpenERP projects
+
+
+
+ 2
+ I use another repository system (SourceForge...)
+
+
+
+ 3
+ I host them on my own website
+
+
+
+ 4
+ I do not publish my developments
+
+
+
diff --git a/addons/survey/data/survey_demo_user.xml b/addons/survey/data/survey_demo_user.xml
new file mode 100644
index 00000000000..26a60c8b2c5
--- /dev/null
+++ b/addons/survey/data/survey_demo_user.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/addons/survey/data/survey_stages.xml b/addons/survey/data/survey_stages.xml
new file mode 100644
index 00000000000..33522d8d3fe
--- /dev/null
+++ b/addons/survey/data/survey_stages.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+ Draft
+
+
+
+
+
+ In progress
+
+
+
+
+
+ Closed
+
+
+
+
+
+ Permanent
+
+
+
+
+
+
diff --git a/addons/survey/i18n/es_MX.po b/addons/survey/i18n/es_MX.po
deleted file mode 100644
index 7c1c9bbbad1..00000000000
--- a/addons/survey/i18n/es_MX.po
+++ /dev/null
@@ -1,1914 +0,0 @@
-# Spanish translation for openobject-addons
-# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2010.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2011-01-11 11:16+0000\n"
-"PO-Revision-Date: 2011-01-18 18:43+0000\n"
-"Last-Translator: Jordi Esteve (www.zikzakmedia.com) "
-"\n"
-"Language-Team: Spanish \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-09-05 05:45+0000\n"
-"X-Generator: Launchpad (build 13830)\n"
-
-#. module: survey
-#: view:survey.print:0
-#: view:survey.print.answer:0
-msgid "Print Option"
-msgstr "Opción imprimir"
-
-#. module: survey
-#: code:addons/survey/survey.py:422
-#, python-format
-msgid ""
-"Minimum Required Answer you entered is "
-"greater than the number of answer. "
-"Please use a number that is smaller than %d."
-msgstr ""
-"El número mínimo de respuestas requeridas que ha introducido es mayor que el "
-"número de respuestas. Por favor, use un número menor que %d."
-
-#. module: survey
-#: view:survey.question.wiz:0
-msgid "Your Messages"
-msgstr "Sus mensajes"
-
-#. module: survey
-#: field:survey.question,comment_valid_type:0
-#: field:survey.question,validation_type:0
-msgid "Text Validation"
-msgstr "Validación del texto"
-
-#. module: survey
-#: code:addons/survey/survey.py:434
-#, python-format
-msgid ""
-"Maximum Required Answer you entered for "
-"your maximum is greater than the number of answer. "
-" Please use a number that is smaller than %d."
-msgstr ""
-"El número máximo de respuestas requeridas que ha introducido para su máximo "
-"es mayor que el número de respuestas. Por favor, use un número menor que %d."
-
-#. module: survey
-#: view:survey:0
-#: field:survey,invited_user_ids:0
-msgid "Invited User"
-msgstr "Usuario invitado"
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Character"
-msgstr "Carácter"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_survey_form1
-#: model:ir.ui.menu,name:survey.menu_print_survey_form
-#: model:ir.ui.menu,name:survey.menu_reporting
-#: model:ir.ui.menu,name:survey.menu_survey_form
-#: model:ir.ui.menu,name:survey.menu_surveys
-msgid "Surveys"
-msgstr "Encuestas"
-
-#. module: survey
-#: view:survey:0
-msgid "Set to draft"
-msgstr "Cambiar a borrador"
-
-#. module: survey
-#: field:survey.question,in_visible_answer_type:0
-msgid "Is Answer Type Invisible?"
-msgstr "¿La respuesta es de tipo invisible?"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-#: view:survey.request:0
-msgid "Group By..."
-msgstr "Agrupar por..."
-
-#. module: survey
-#: view:survey.send.invitation.log:0
-msgid "Results :"
-msgstr "Resultados :"
-
-#. module: survey
-#: view:survey.request:0
-msgid "Survey Request"
-msgstr "Solicitud de encuesta"
-
-#. module: survey
-#: selection:survey.question,required_type:0
-msgid "A Range"
-msgstr "Un rango"
-
-#. module: survey
-#: view:survey.response.line:0
-msgid "Table Answer"
-msgstr "Tabla de respuesta"
-
-#. module: survey
-#: field:survey.history,date:0
-msgid "Date started"
-msgstr "Fecha de inicio"
-
-#. module: survey
-#: field:survey,history:0
-msgid "History Lines"
-msgstr "Líneas histórico"
-
-#. module: survey
-#: code:addons/survey/survey.py:448
-#, python-format
-msgid ""
-"You must enter one or more menu choices in "
-"column heading (white spaces not allowed)"
-msgstr ""
-"Debe introducir una o más opciones de menú en la cabecera de columna (no se "
-"permiten espacios en blanco)"
-
-#. module: survey
-#: field:survey.question.column.heading,in_visible_menu_choice:0
-msgid "Is Menu Choice Invisible??"
-msgstr "¿La opción de menú es invisible?"
-
-#. module: survey
-#: field:survey.send.invitation,mail:0
-msgid "Body"
-msgstr "Cuerpo"
-
-#. module: survey
-#: field:survey.question,allow_comment:0
-msgid "Allow Comment Field"
-msgstr "Permitir campo comentario"
-
-#. module: survey
-#: selection:survey.print,paper_size:0
-#: selection:survey.print.answer,paper_size:0
-msgid "A4 (210mm x 297mm)"
-msgstr "A4 (210mm x 297mm)"
-
-#. module: survey
-#: field:survey.question,comment_maximum_date:0
-#: field:survey.question,validation_maximum_date:0
-msgid "Maximum date"
-msgstr "Fecha Máxima"
-
-#. module: survey
-#: field:survey.question,in_visible_menu_choice:0
-msgid "Is Menu Choice Invisible?"
-msgstr "¿La opción de menú es invisible?"
-
-#. module: survey
-#: view:survey:0
-msgid "Completed"
-msgstr "Completada"
-
-#. module: survey
-#: selection:survey.question,required_type:0
-msgid "Exactly"
-msgstr "Exactamente"
-
-#. module: survey
-#: view:survey:0
-msgid "Open Date"
-msgstr "Fecha de Inicio"
-
-#. module: survey
-#: view:survey.request:0
-msgid "Set to Draft"
-msgstr "Cambiar a borrador"
-
-#. module: survey
-#: field:survey.question,is_comment_require:0
-msgid "Add Comment Field"
-msgstr "Campo para agregar comentario"
-
-#. module: survey
-#: code:addons/survey/survey.py:401
-#, python-format
-msgid ""
-"#Required Answer you entered is greater "
-"than the number of answer. Please use a "
-"number that is smaller than %d."
-msgstr ""
-"Número de respuestas requeridas que ha escrito es mayor que el número de "
-"respuestas. Introduzca un número menor que %d."
-
-#. module: survey
-#: field:survey.question,tot_resp:0
-msgid "Total Answer"
-msgstr "Total respuesta"
-
-#. module: survey
-#: field:survey.tbl.column.heading,name:0
-msgid "Row Number"
-msgstr "Número de Fila"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_name_wiz
-msgid "survey.name.wiz"
-msgstr "encuesta.nombre.asist"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_survey_question_form
-msgid "Survey Questions"
-msgstr "Preguntas de las encuestas"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Matrix of Choices (Only One Answers Per Row)"
-msgstr "Matriz de selección (solamente una respuesta por fila)"
-
-#. module: survey
-#: code:addons/survey/survey.py:475
-#, python-format
-msgid ""
-"Maximum Required Answer you entered for your maximum is greater than the "
-"number of answer. Please use a number that is smaller than %d."
-msgstr ""
-"El número máximo de respuestas requeridas que ha introducido para su máximo "
-"es mayor que el número de respuestas. Por favor, use un número menor que %d."
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_question_message
-#: model:ir.model,name:survey.model_survey_question
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Survey Question"
-msgstr "Pregunta de la encuesta"
-
-#. module: survey
-#: view:survey.question.column.heading:0
-msgid "Use if question type is rating_scale"
-msgstr "Utilizar si la pregunta es de tipo calificación_escala"
-
-#. module: survey
-#: field:survey.print,page_number:0
-#: field:survey.print.answer,page_number:0
-msgid "Include Page Number"
-msgstr "Incluir número de página"
-
-#. module: survey
-#: view:survey.page:0
-#: view:survey.question:0
-#: view:survey.send.invitation.log:0
-msgid "Ok"
-msgstr "Aceptar"
-
-#. module: survey
-#: field:survey.page,title:0
-msgid "Page Title"
-msgstr "Título de la página"
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_define_survey
-msgid "Define Surveys"
-msgstr "Definir encuestas"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_history
-msgid "Survey History"
-msgstr "Histórico encuestas"
-
-#. module: survey
-#: field:survey.response.answer,comment:0
-#: field:survey.response.line,comment:0
-msgid "Notes"
-msgstr "Notas"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.request:0
-msgid "Search Survey"
-msgstr "Buscar encuesta"
-
-#. module: survey
-#: field:survey.response.answer,answer:0
-#: field:survey.tbl.column.heading,value:0
-msgid "Value"
-msgstr "Valor"
-
-#. module: survey
-#: field:survey.question,column_heading_ids:0
-msgid " Column heading"
-msgstr " Cabecera columna"
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_run_survey_form
-msgid "Answer a Survey"
-msgstr "Responder una encuesta"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:92
-#, python-format
-msgid "Error!"
-msgstr "¡Error!"
-
-#. module: survey
-#: field:survey,tot_comp_survey:0
-msgid "Total Completed Survey"
-msgstr "Total encuestas completadas"
-
-#. module: survey
-#: view:survey.response.answer:0
-msgid "(Use Only Question Type is matrix_of_drop_down_menus)"
-msgstr "(usar sólo cuando el tipo de pregunta sea matrix_of_drop_down_menus)"
-
-#. module: survey
-#: model:ir.actions.report.xml,name:survey.survey_analysis
-msgid "Survey Statistics"
-msgstr "Estadísticas encuestas"
-
-#. module: survey
-#: selection:survey,state:0
-#: view:survey.request:0
-#: selection:survey.request,state:0
-msgid "Cancelled"
-msgstr "Cancelada"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Rating Scale"
-msgstr "Escala de calificación"
-
-#. module: survey
-#: field:survey.question,comment_field_type:0
-msgid "Comment Field Type"
-msgstr "Campo tipo comentario"
-
-#. module: survey
-#: code:addons/survey/survey.py:375
-#: code:addons/survey/survey.py:387
-#: code:addons/survey/survey.py:401
-#: code:addons/survey/survey.py:406
-#: code:addons/survey/survey.py:416
-#: code:addons/survey/survey.py:422
-#: code:addons/survey/survey.py:428
-#: code:addons/survey/survey.py:434
-#: code:addons/survey/survey.py:438
-#: code:addons/survey/survey.py:444
-#: code:addons/survey/survey.py:448
-#: code:addons/survey/survey.py:458
-#: code:addons/survey/survey.py:462
-#: code:addons/survey/survey.py:467
-#: code:addons/survey/survey.py:473
-#: code:addons/survey/survey.py:475
-#: code:addons/survey/survey.py:477
-#: code:addons/survey/survey.py:482
-#: code:addons/survey/survey.py:484
-#: code:addons/survey/survey.py:642
-#: code:addons/survey/wizard/survey_answer.py:124
-#: code:addons/survey/wizard/survey_answer.py:131
-#: code:addons/survey/wizard/survey_answer.py:700
-#: code:addons/survey/wizard/survey_answer.py:739
-#: code:addons/survey/wizard/survey_answer.py:759
-#: code:addons/survey/wizard/survey_answer.py:788
-#: code:addons/survey/wizard/survey_answer.py:793
-#: code:addons/survey/wizard/survey_answer.py:801
-#: code:addons/survey/wizard/survey_answer.py:812
-#: code:addons/survey/wizard/survey_answer.py:821
-#: code:addons/survey/wizard/survey_answer.py:826
-#: code:addons/survey/wizard/survey_answer.py:900
-#: code:addons/survey/wizard/survey_answer.py:936
-#: code:addons/survey/wizard/survey_answer.py:954
-#: code:addons/survey/wizard/survey_answer.py:982
-#: code:addons/survey/wizard/survey_answer.py:985
-#: code:addons/survey/wizard/survey_answer.py:988
-#: code:addons/survey/wizard/survey_answer.py:1000
-#: code:addons/survey/wizard/survey_answer.py:1007
-#: code:addons/survey/wizard/survey_answer.py:1010
-#: code:addons/survey/wizard/survey_selection.py:134
-#: code:addons/survey/wizard/survey_selection.py:138
-#: code:addons/survey/wizard/survey_send_invitation.py:74
-#, python-format
-msgid "Warning !"
-msgstr "¡ Advertencia !"
-
-#. module: survey
-#: selection:survey.question,comment_field_type:0
-msgid "Single Line Of Text"
-msgstr "Única línea de texto"
-
-#. module: survey
-#: view:survey.send.invitation:0
-#: field:survey.send.invitation,send_mail_existing:0
-msgid "Send Reminder for Existing User"
-msgstr "Enviar recordatorio para usuario existente"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Multiple Choice (Multiple Answer)"
-msgstr "Selección múltiple (mútiples respuestas)"
-
-#. module: survey
-#: view:survey:0
-msgid "Edit Survey"
-msgstr "Editar encuesta"
-
-#. module: survey
-#: view:survey.response.line:0
-msgid "Survey Answer Line"
-msgstr "Líne de respuesta encuesta"
-
-#. module: survey
-#: field:survey.question.column.heading,menu_choice:0
-msgid "Menu Choice"
-msgstr "Selección Menú"
-
-#. module: survey
-#: selection:survey.question,required_type:0
-msgid "At Most"
-msgstr "Como máximo"
-
-#. module: survey
-#: field:survey.question,is_validation_require:0
-msgid "Validate Text"
-msgstr "Validar texto"
-
-#. module: survey
-#: field:survey.response.line,single_text:0
-msgid "Text"
-msgstr "Texto"
-
-#. module: survey
-#: constraint:res.users:0
-msgid "The chosen company is not in the allowed companies for this user"
-msgstr ""
-"La compañía seleccionada no está en las compañías permitidas para este "
-"usuario"
-
-#. module: survey
-#: selection:survey.print,paper_size:0
-#: selection:survey.print.answer,paper_size:0
-msgid "Letter (8.5\" x 11\")"
-msgstr "Carta (8.5\" x 11\")"
-
-#. module: survey
-#: view:survey:0
-#: field:survey,responsible_id:0
-msgid "Responsible"
-msgstr "Responsable"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_request
-msgid "survey.request"
-msgstr "solicitud.encuesta"
-
-#. module: survey
-#: field:survey.send.invitation,mail_subject:0
-#: field:survey.send.invitation,mail_subject_existing:0
-msgid "Subject"
-msgstr "Asunto"
-
-#. module: survey
-#: field:survey.question,comment_maximum_float:0
-#: field:survey.question,validation_maximum_float:0
-msgid "Maximum decimal number"
-msgstr "Máximo número de decimales"
-
-#. module: survey
-#: view:survey.request:0
-msgid "Late"
-msgstr "Retrasado"
-
-#. module: survey
-#: sql_constraint:res.users:0
-msgid "You can not have two users with the same login !"
-msgstr "¡No puede tener dos usuarios con el mismo identificador de usuario!"
-
-#. module: survey
-#: field:survey.send.invitation,mail_from:0
-msgid "From"
-msgstr "De"
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Don't Validate Comment Text."
-msgstr "No validar texto de comentario"
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Must Be A Whole Number"
-msgstr "Debe ser un número entero"
-
-#. module: survey
-#: field:survey.answer,question_id:0
-#: field:survey.page,question_ids:0
-#: field:survey.question,question:0
-#: field:survey.question.column.heading,question_id:0
-#: field:survey.response.line,question_id:0
-msgid "Question"
-msgstr "Pregunta"
-
-#. module: survey
-#: view:survey.page:0
-msgid "Search Survey Page"
-msgstr "Buscar página de la encuesta"
-
-#. module: survey
-#: view:survey.send.invitation:0
-msgid "Send"
-msgstr "Enviar"
-
-#. module: survey
-#: field:survey.question.wiz,name:0
-msgid "Number"
-msgstr "Número"
-
-#. module: survey
-#: code:addons/survey/survey.py:444
-#, python-format
-msgid ""
-"You must enter one or more menu choices in "
-"column heading"
-msgstr ""
-"Debe introducir una o más opciones de menú en el encabezado de la columna"
-
-#. module: survey
-#: model:ir.actions.act_window,help:survey.action_survey_form1
-msgid ""
-"You can create survey for different purposes: recruitment interviews, "
-"employee's periodical evaluations, marketing campaigns, etc. A survey is "
-"made of pages containing questions of several types: text, multiple choices, "
-"etc. You can edit survey manually or click on the 'Edit Survey' for a "
-"WYSIWYG interface."
-msgstr ""
-"Puede crear encuestas para diferentes propósitos: entrevistas de selección "
-"de personal, evaluaciones periódicas de los empleados, campañas de "
-"marketing, etc. Una encuesta se compone de páginas que contienen preguntas "
-"de varios tipos: texto, opciones múltiples, etc. Puede editar la encuesta "
-"manualmente o hacer clic en \"Editar encuesta” para una interfaz WYSIWYG."
-
-#. module: survey
-#: view:survey:0
-#: view:survey.request:0
-#: field:survey.request,state:0
-msgid "State"
-msgstr "Estado"
-
-#. module: survey
-#: view:survey.request:0
-msgid "Evaluation Plan Phase"
-msgstr "Fase del plan de evaluación"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Between"
-msgstr "Entre"
-
-#. module: survey
-#: view:survey.print:0
-#: view:survey.print.answer:0
-#: view:survey.print.statistics:0
-msgid "Print"
-msgstr "Imprimir"
-
-#. module: survey
-#: field:survey.question,make_comment_field:0
-msgid "Make Comment Field an Answer Choice"
-msgstr "Hacer campo comentario como opción de respuesta"
-
-#. module: survey
-#: view:survey:0
-#: field:survey,type:0
-msgid "Type"
-msgstr "Tipo"
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Email"
-msgstr "Email"
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_answer_surveys
-msgid "Answer Surveys"
-msgstr "Reponder encuestas"
-
-#. module: survey
-#: selection:survey.response,state:0
-msgid "Not Finished"
-msgstr "No teminado"
-
-#. module: survey
-#: view:survey.print:0
-msgid "Survey Print"
-msgstr "Imprimir encuesta"
-
-#. module: survey
-#: view:survey.send.invitation:0
-msgid "Select Partner"
-msgstr "Seleccionar empresa"
-
-#. module: survey
-#: field:survey.question,type:0
-msgid "Question Type"
-msgstr "Tipo pregunta"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:131
-#, python-format
-msgid "You can not answer this survey more than %s times"
-msgstr "No puede responder a esta encuesta más de '%s' veces"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.act_survey_answer
-msgid "Answers"
-msgstr "Respuestas"
-
-#. module: survey
-#: model:ir.module.module,description:survey.module_meta_information
-msgid ""
-"\n"
-" This module is used for surveying. It depends on the answers or reviews "
-"of some questions by different users.\n"
-" A survey may have multiple pages. Each page may contain multiple "
-"questions and each question may have multiple answers.\n"
-" Different users may give different answers of question and according to "
-"that survey is done. \n"
-" Partners are also sent mails with user name and password for the "
-"invitation of the survey\n"
-" "
-msgstr ""
-"\n"
-" Este módulo se usa para realizar encuestas. Se basa en las respuestas o "
-"comentarios de los usuarios a varias preguntas.\n"
-" Una encuesta puede tener varias páginas. Cada página puede contener "
-"múltiples preguntas y cada pregunta puede tener varias respuestas.\n"
-" Diferentes usuarios pueden dar diferentes respuestas a la pregunta de "
-"acuerdo a como esté confeccionada la encuesta.\n"
-" También se puede invitar a las empresas a responder una encuesta, "
-"enviándoles correos electrónicos con nombre de usuario y contraseña.\n"
-" "
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:124
-#, python-format
-msgid "You can not answer because the survey is not open"
-msgstr "No puede responder porque la encuesta no está abierta"
-
-#. module: survey
-#: selection:survey.response,response_type:0
-msgid "Link"
-msgstr "Vínculo"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_survey_type_form
-#: model:ir.model,name:survey.model_survey_type
-#: view:survey.type:0
-msgid "Survey Type"
-msgstr "Tipo de encuesta"
-
-#. module: survey
-#: field:survey.page,sequence:0
-msgid "Page Nr"
-msgstr "Nº página"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-#: field:survey.question,descriptive_text:0
-#: selection:survey.question,type:0
-msgid "Descriptive Text"
-msgstr "Texto descriptivo"
-
-#. module: survey
-#: field:survey.question,minimum_req_ans:0
-msgid "Minimum Required Answer"
-msgstr "Respuesta mínima requerida"
-
-#. module: survey
-#: code:addons/survey/survey.py:484
-#, python-format
-msgid ""
-"You must enter one or more menu choices in column heading (white spaces not "
-"allowed)"
-msgstr ""
-"Debe introducir una o más opciones de menú en el encabezado de la columna "
-"(espacios en blanco no está permitidos)"
-
-#. module: survey
-#: field:survey.question,req_error_msg:0
-msgid "Error Message"
-msgstr "Mensaje de error"
-
-#. module: survey
-#: code:addons/survey/survey.py:482
-#, python-format
-msgid "You must enter one or more menu choices in column heading"
-msgstr "Debe introducir una o más opciones de menú en la cabecera de columna"
-
-#. module: survey
-#: field:survey.request,date_deadline:0
-msgid "Deadline date"
-msgstr "Fecha límite"
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Must Be A Date"
-msgstr "Debe ser una fecha"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_print
-msgid "survey.print"
-msgstr "encuesta.imprimir"
-
-#. module: survey
-#: view:survey.question.column.heading:0
-#: field:survey.question.column.heading,title:0
-msgid "Column Heading"
-msgstr "Cabecera columna"
-
-#. module: survey
-#: field:survey.question,is_require_answer:0
-msgid "Require Answer to Question"
-msgstr "Respuesta obligatoria a la pregunta"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_survey_request_tree
-#: model:ir.ui.menu,name:survey.menu_survey_type_form1
-msgid "Survey Requests"
-msgstr "Solicitudes de encuestas"
-
-#. module: survey
-#: code:addons/survey/survey.py:375
-#: code:addons/survey/survey.py:462
-#, python-format
-msgid "You must enter one or more column heading."
-msgstr "Debe introducir una o más cabeceras de columna."
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:759
-#: code:addons/survey/wizard/survey_answer.py:954
-#, python-format
-msgid "Please enter an integer value"
-msgstr "Por favor introduzca un valor numérico entero"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_browse_answer
-msgid "survey.browse.answer"
-msgstr "encuesta.explorar.respuestas"
-
-#. module: survey
-#: selection:survey.question,comment_field_type:0
-msgid "Paragraph of Text"
-msgstr "Párrafo de texto"
-
-#. module: survey
-#: code:addons/survey/survey.py:428
-#, python-format
-msgid ""
-"Maximum Required Answer you entered for "
-"your maximum is greater than the number of answer. "
-" Please use a number that is smaller than %d."
-msgstr ""
-"El número máximo de respuestas requeridas que ha introducido para su máximo "
-"es mayor que el número de respuestas. Por favor, use un número menor que %d."
-
-#. module: survey
-#: view:survey.request:0
-msgid "Watting Answer"
-msgstr "Esperando respuesta"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "When the question is not answered, display this error message:"
-msgstr ""
-"Cuando la respuesta no sea contestada, mostrar este mensaje de error:"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Options"
-msgstr "Opciones"
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_browse_survey_response
-msgid "Browse Answers"
-msgstr "Buscar respuestas"
-
-#. module: survey
-#: field:survey.response.answer,comment_field:0
-#: view:survey.response.line:0
-msgid "Comment"
-msgstr "Comentario"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_answer
-#: model:ir.model,name:survey.model_survey_response_answer
-#: view:survey.answer:0
-#: view:survey.response:0
-#: view:survey.response.answer:0
-#: view:survey.response.line:0
-msgid "Survey Answer"
-msgstr "Respuesta encuesta"
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Selection"
-msgstr "Selección"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_browse_survey_response
-#: view:survey:0
-msgid "Answer Survey"
-msgstr "Responder encuesta"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Comment Field"
-msgstr "Campo comentario"
-
-#. module: survey
-#: selection:survey.response,response_type:0
-msgid "Manually"
-msgstr "Manualmente"
-
-#. module: survey
-#: help:survey,responsible_id:0
-msgid "User responsible for survey"
-msgstr "Usuario responsable de la encuesta."
-
-#. module: survey
-#: field:survey.question,comment_column:0
-msgid "Add comment column in matrix"
-msgstr "Añadir columna de comentarios en la matriz"
-
-#. module: survey
-#: field:survey.answer,response:0
-msgid "#Answer"
-msgstr "#Respuesta"
-
-#. module: survey
-#: field:survey.print,without_pagebreak:0
-#: field:survey.print.answer,without_pagebreak:0
-msgid "Print Without Page Breaks"
-msgstr "Imprimir sin saltos de página"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "When the comment is an invalid format, display this error message"
-msgstr ""
-"Mostrar este mensaje de error cuando el comentario esté en un formato no "
-"válido"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_selection.py:138
-#, python-format
-msgid ""
-"You can not give more response. Please contact the author of this survey for "
-"further assistance."
-msgstr ""
-"No puede dar más respuestas. Póngase en contacto con el autor de esta "
-"encuesta para obtener más ayuda."
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.act_survey_page_question
-#: model:ir.actions.act_window,name:survey.act_survey_question
-msgid "Questions"
-msgstr "Preguntas"
-
-#. module: survey
-#: help:survey,response_user:0
-msgid "Set to one if you require only one Answer per user"
-msgstr "Establecer a uno si sólo requiere una respuesta por usuario."
-
-#. module: survey
-#: field:survey,users:0
-msgid "Users"
-msgstr "Usuarios"
-
-#. module: survey
-#: view:survey.send.invitation:0
-msgid "Message"
-msgstr "Mensaje"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.request:0
-msgid "MY"
-msgstr "MI"
-
-#. module: survey
-#: field:survey.question,maximum_req_ans:0
-msgid "Maximum Required Answer"
-msgstr "Máximas respuestas requeridas"
-
-#. module: survey
-#: field:survey.name.wiz,page_no:0
-msgid "Page Number"
-msgstr "Número de página"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:92
-#, python-format
-msgid "Cannot locate survey for the question wizard!"
-msgstr "¡No se pudo localizar la encuesta para el asistente de preguntas!"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "and"
-msgstr "y"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_print_statistics
-#: view:survey.print.statistics:0
-msgid "Survey Print Statistics"
-msgstr "Imprimir estadísticas de encuestas"
-
-#. module: survey
-#: field:survey.send.invitation.log,note:0
-msgid "Log"
-msgstr "Registro (Log)"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "When the choices do not add up correctly, display this error message"
-msgstr ""
-"Mostrar este mensaje de error cuando las selecciones no totalicen "
-"correctamente"
-
-#. module: survey
-#: field:survey,date_close:0
-msgid "Survey Close Date"
-msgstr "Fecha de cierre encuestas"
-
-#. module: survey
-#: field:survey,date_open:0
-msgid "Survey Open Date"
-msgstr "Fecha apertura de encuesta"
-
-#. module: survey
-#: field:survey.question.column.heading,in_visible_rating_weight:0
-msgid "Is Rating Scale Invisible ??"
-msgstr "¿La escala de calificación es invisible?"
-
-#. module: survey
-#: view:survey.browse.answer:0
-#: view:survey.name.wiz:0
-msgid "Start"
-msgstr "Inicio"
-
-#. module: survey
-#: code:addons/survey/survey.py:477
-#, python-format
-msgid "Maximum Required Answer is greater than Minimum Required Answer"
-msgstr ""
-"El número máximo de respuestas requeridas es mayor que el mínimo de "
-"respuestas requeridas."
-
-#. module: survey
-#: field:survey.question,comment_maximum_no:0
-#: field:survey.question,validation_maximum_no:0
-msgid "Maximum number"
-msgstr "Número máximo"
-
-#. module: survey
-#: selection:survey,state:0
-#: selection:survey.request,state:0
-#: selection:survey.response.line,state:0
-msgid "Draft"
-msgstr "Borrador"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_print_statistics
-msgid "survey.print.statistics"
-msgstr "encuesta.imprimir.estadisticas"
-
-#. module: survey
-#: selection:survey,state:0
-msgid "Closed"
-msgstr "Cerrada"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Matrix of Drop-down Menus"
-msgstr "Matriz de menús desplegables"
-
-#. module: survey
-#: view:survey:0
-#: field:survey.answer,answer:0
-#: field:survey.name.wiz,response:0
-#: view:survey.page:0
-#: view:survey.print.answer:0
-#: field:survey.print.answer,response_ids:0
-#: view:survey.question:0
-#: field:survey.question,answer_choice_ids:0
-#: field:survey.request,response:0
-#: field:survey.response,question_ids:0
-#: field:survey.response.answer,answer_id:0
-#: field:survey.response.answer,response_id:0
-#: view:survey.response.line:0
-#: field:survey.response.line,response_answer_ids:0
-#: field:survey.response.line,response_id:0
-#: field:survey.response.line,response_table_ids:0
-#: field:survey.send.invitation,partner_ids:0
-#: field:survey.tbl.column.heading,response_table_id:0
-msgid "Answer"
-msgstr "Respuesta"
-
-#. module: survey
-#: field:survey,max_response_limit:0
-msgid "Maximum Answer Limit"
-msgstr "Límite máximo de respuesta"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_act_view_survey_send_invitation
-msgid "Send Invitations"
-msgstr "Enviar invitaciones"
-
-#. module: survey
-#: field:survey.name.wiz,store_ans:0
-msgid "Store Answer"
-msgstr "Guardar respuesta"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Date and Time"
-msgstr "Fecha y hora"
-
-#. module: survey
-#: field:survey,state:0
-#: field:survey.response,state:0
-#: field:survey.response.line,state:0
-msgid "Status"
-msgstr "Estado"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_print
-msgid "Print Survey"
-msgstr "Imprimir encuesta"
-
-#. module: survey
-#: field:survey,send_response:0
-msgid "E-mail Notification on Answer"
-msgstr "Email de notificación sobre la respuesta"
-
-#. module: survey
-#: field:survey.response.answer,value_choice:0
-msgid "Value Choice"
-msgstr "Valor selección"
-
-#. module: survey
-#: view:survey:0
-msgid "Started"
-msgstr "Iniciada"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_print_answer
-#: view:survey:0
-#: view:survey.print.answer:0
-msgid "Print Answer"
-msgstr "Imprimir respuesta"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Multiple Textboxes"
-msgstr "Campos de texto múltiples"
-
-#. module: survey
-#: selection:survey.print,orientation:0
-#: selection:survey.print.answer,orientation:0
-msgid "Landscape(Horizontal)"
-msgstr "Horizontal"
-
-#. module: survey
-#: field:survey.question,no_of_rows:0
-msgid "No of Rows"
-msgstr "Nº de columnas"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.name.wiz:0
-msgid "Survey Details"
-msgstr "Detalles encuesta"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Multiple Textboxes With Different Type"
-msgstr "Campos de texto múltiples con tipo diferente"
-
-#. module: survey
-#: view:survey.question.column.heading:0
-msgid "Menu Choices (each choice on separate lines)"
-msgstr "Opciones de menú (cada opción en líneas separadas)"
-
-#. module: survey
-#: field:survey.response,response_type:0
-msgid "Answer Type"
-msgstr "Tipo respuesta"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Validation"
-msgstr "Validación"
-
-#. module: survey
-#: view:survey.request:0
-#: selection:survey.request,state:0
-msgid "Waiting Answer"
-msgstr "Esperando respuesta"
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Must Be A Decimal Number"
-msgstr "Debe ser un número decimal"
-
-#. module: survey
-#: field:res.users,survey_id:0
-msgid "Groups"
-msgstr "Grupos"
-
-#. module: survey
-#: selection:survey.answer,type:0
-#: selection:survey.question,type:0
-msgid "Date"
-msgstr "Fecha"
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Integer"
-msgstr "Entero"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_send_invitation
-msgid "survey.send.invitation"
-msgstr "encuesta.enviar.invitacion"
-
-#. module: survey
-#: field:survey.history,user_id:0
-#: view:survey.request:0
-#: field:survey.request,user_id:0
-#: field:survey.response,user_id:0
-msgid "User"
-msgstr "Usuario"
-
-#. module: survey
-#: field:survey.name.wiz,transfer:0
-msgid "Page Transfer"
-msgstr "Página de transferencia"
-
-#. module: survey
-#: selection:survey.response.line,state:0
-msgid "Skiped"
-msgstr "Omitido"
-
-#. module: survey
-#: field:survey.print,paper_size:0
-#: field:survey.print.answer,paper_size:0
-msgid "Paper Size"
-msgstr "Tamaño del papel"
-
-#. module: survey
-#: field:survey.response.answer,column_id:0
-#: field:survey.tbl.column.heading,column_id:0
-msgid "Column"
-msgstr "Columna"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_tbl_column_heading
-msgid "survey.tbl.column.heading"
-msgstr "encuesta.tbl.columna.cabecera"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_response_line
-msgid "Survey Response Line"
-msgstr "Línea de respuesta de encuesta"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_selection.py:134
-#, python-format
-msgid "You can not give response for this survey more than %s times"
-msgstr "No puede responder esta encuesta más de %s veces"
-
-#. module: survey
-#: model:ir.actions.report.xml,name:survey.report_survey_form
-#: model:ir.model,name:survey.model_survey
-#: view:survey:0
-#: view:survey.browse.answer:0
-#: field:survey.browse.answer,survey_id:0
-#: field:survey.history,survey_id:0
-#: view:survey.name.wiz:0
-#: field:survey.name.wiz,survey_id:0
-#: view:survey.page:0
-#: field:survey.page,survey_id:0
-#: view:survey.print:0
-#: field:survey.print,survey_ids:0
-#: field:survey.print.statistics,survey_ids:0
-#: field:survey.question,survey:0
-#: view:survey.request:0
-#: field:survey.request,survey_id:0
-#: field:survey.response,survey_id:0
-msgid "Survey"
-msgstr "Encuesta"
-
-#. module: survey
-#: field:survey.question,in_visible_rating_weight:0
-msgid "Is Rating Scale Invisible?"
-msgstr "¿La escala de calificación es invisible?"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Numerical Textboxes"
-msgstr "Campos de texto numéricos"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_question_wiz
-msgid "survey.question.wiz"
-msgstr "enquesta.pregunta.asist"
-
-#. module: survey
-#: view:survey:0
-msgid "History"
-msgstr "Historial"
-
-#. module: survey
-#: help:survey.browse.answer,response_id:0
-msgid ""
-"If this field is empty, all answers of the selected survey will be print."
-msgstr ""
-"Si este campo está vacío, se imprimirán todas las respuestas de la encuesta "
-"seleccionada."
-
-#. module: survey
-#: field:survey.type,code:0
-msgid "Code"
-msgstr "Código"
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_print_survey_statistics
-msgid "Surveys Statistics"
-msgstr "Estadísticas de encuestas"
-
-#. module: survey
-#: field:survey.print,orientation:0
-#: field:survey.print.answer,orientation:0
-msgid "Orientation"
-msgstr "Orientación"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.answer:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Seq"
-msgstr "Secuencia"
-
-#. module: survey
-#: field:survey.request,email:0
-msgid "E-mail"
-msgstr "Email"
-
-#. module: survey
-#: field:survey.question,comment_minimum_no:0
-#: field:survey.question,validation_minimum_no:0
-msgid "Minimum number"
-msgstr "Número mínimo"
-
-#. module: survey
-#: field:survey.question,req_ans:0
-msgid "#Required Answer"
-msgstr "Nº de respuestas requeridas"
-
-#. module: survey
-#: field:survey.answer,sequence:0
-#: field:survey.question,sequence:0
-msgid "Sequence"
-msgstr "Secuencia"
-
-#. module: survey
-#: field:survey.question,comment_label:0
-msgid "Field Label"
-msgstr "Etiqueta del campo"
-
-#. module: survey
-#: view:survey:0
-msgid "Other"
-msgstr "Otros"
-
-#. module: survey
-#: view:survey.request:0
-#: selection:survey.request,state:0
-msgid "Done"
-msgstr "Realizado"
-
-#. module: survey
-#: view:survey:0
-msgid "Test Survey"
-msgstr "Probar encuesta"
-
-#. module: survey
-#: field:survey.question,rating_allow_one_column_require:0
-msgid "Allow Only One Answer per Column (Forced Ranking)"
-msgstr "Permitir una sóla respuesta por columna (clasificación forzada)"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.browse.answer:0
-#: view:survey.name.wiz:0
-#: view:survey.print:0
-#: view:survey.print.answer:0
-#: view:survey.print.statistics:0
-#: view:survey.send.invitation:0
-msgid "Cancel"
-msgstr "Cancelar"
-
-#. module: survey
-#: view:survey:0
-msgid "Close"
-msgstr "Cerrar"
-
-#. module: survey
-#: field:survey.question,comment_minimum_float:0
-#: field:survey.question,validation_minimum_float:0
-msgid "Minimum decimal number"
-msgstr "Número decimal mínimo"
-
-#. module: survey
-#: view:survey:0
-#: selection:survey,state:0
-msgid "Open"
-msgstr "Abrir"
-
-#. module: survey
-#: field:survey,tot_start_survey:0
-msgid "Total Started Survey"
-msgstr "Total encuestas empezadas"
-
-#. module: survey
-#: code:addons/survey/survey.py:467
-#, python-format
-msgid ""
-"#Required Answer you entered is greater than the number of answer. Please "
-"use a number that is smaller than %d."
-msgstr ""
-"El número de respuestas requeridas que ha escrito es mayor que el número de "
-"respuestas. Introduzca un número menor que %d."
-
-#. module: survey
-#: help:survey,max_response_limit:0
-msgid "Set to one if survey is answerable only once"
-msgstr "Establecer a uno si la encuesta sólo puede responderse una vez."
-
-#. module: survey
-#: selection:survey.response,state:0
-msgid "Finished "
-msgstr "Terminado "
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_question_column_heading
-msgid "Survey Question Column Heading"
-msgstr "Cabecera de columna de pregunta de encuesta"
-
-#. module: survey
-#: field:survey.answer,average:0
-msgid "#Avg"
-msgstr "#Prom."
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Matrix of Choices (Multiple Answers Per Row)"
-msgstr "Matriz de opciones (múltiples respuestas por fila)"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_name
-msgid "Give Survey Answer"
-msgstr "Responder encuesta"
-
-#. module: survey
-#: model:ir.model,name:survey.model_res_users
-msgid "res.users"
-msgstr "res.usuarios"
-
-#. module: survey
-#: view:survey:0
-msgid "Current"
-msgstr "Actual"
-
-#. module: survey
-#: selection:survey.response.line,state:0
-msgid "Answered"
-msgstr "Contestadas"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:433
-#, python-format
-msgid "Complete Survey Answer"
-msgstr "Respuesta completa de la encuesta"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Comment/Essay Box"
-msgstr "Campo de comentarios/redacción"
-
-#. module: survey
-#: field:survey.answer,type:0
-msgid "Type of Answer"
-msgstr "Tipo de respuesta"
-
-#. module: survey
-#: field:survey.question,required_type:0
-msgid "Respondent must answer"
-msgstr "El encuestado debe responder"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_send_invitation
-#: view:survey.send.invitation:0
-msgid "Send Invitation"
-msgstr "Enviar invitación"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:793
-#, python-format
-msgid "You cannot select the same answer more than one time"
-msgstr "No se puede seleccionar la misma respuesta más de una vez"
-
-#. module: survey
-#: view:survey.question:0
-msgid "Search Question"
-msgstr "Buscar pregunta"
-
-#. module: survey
-#: field:survey,title:0
-msgid "Survey Title"
-msgstr "Título de la encuesta"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Single Textbox"
-msgstr "Campo de texto único"
-
-#. module: survey
-#: field:survey,note:0
-#: field:survey.name.wiz,note:0
-#: view:survey.page:0
-#: field:survey.page,note:0
-#: view:survey.response.line:0
-msgid "Description"
-msgstr "Descripción"
-
-#. module: survey
-#: view:survey.name.wiz:0
-msgid "Select Survey"
-msgstr "Seleccionar encuesta"
-
-#. module: survey
-#: selection:survey.question,required_type:0
-msgid "At Least"
-msgstr "Al menos"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_send_invitation_log
-#: model:ir.model,name:survey.model_survey_send_invitation_log
-msgid "survey.send.invitation.log"
-msgstr "encuesta.enviar.invitacion.registro"
-
-#. module: survey
-#: selection:survey.print,orientation:0
-#: selection:survey.print.answer,orientation:0
-msgid "Portrait(Vertical)"
-msgstr "Retrato (Vertical)"
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Must Be Specific Length"
-msgstr "Debe ser de longitud específica"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: field:survey.question,page_id:0
-msgid "Survey Page"
-msgstr "Página de la encuesta"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Required Answer"
-msgstr "Respuesta requerida"
-
-#. module: survey
-#: code:addons/survey/survey.py:473
-#, python-format
-msgid ""
-"Minimum Required Answer you entered is greater than the number of answer. "
-"Please use a number that is smaller than %d."
-msgstr ""
-"El mínimo de respuestas requeridas que ha introducido es mayor que el número "
-"de respuestas. Por favor, use un número menor que %d."
-
-#. module: survey
-#: code:addons/survey/survey.py:458
-#, python-format
-msgid "You must enter one or more answer."
-msgstr "Debe dar una o más respuestas."
-
-#. module: survey
-#: model:ir.actions.report.xml,name:survey.survey_browse_response
-#: field:survey.browse.answer,response_id:0
-msgid "Survey Answers"
-msgstr "Respuestas encuesta"
-
-#. module: survey
-#: view:survey.browse.answer:0
-msgid "Select Survey and Related Answer"
-msgstr "Seleccione encuesta y respuesta relacionada"
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_print_survey_answer
-msgid "Surveys Answers"
-msgstr "Respuestas encuestas"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.act_survey_pages
-msgid "Pages"
-msgstr "Páginas"
-
-#. module: survey
-#: code:addons/survey/survey.py:406
-#, python-format
-msgid ""
-"#Required Answer you entered is greater "
-"than the number of answer. Please use a "
-"number that is smaller than %d."
-msgstr ""
-"El número de respuestas requeridas que ha introducido es mayor que el número "
-"de respuestas. Utilice un número menor que %d."
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:985
-#, python-format
-msgid "You cannot select same answer more than one time'"
-msgstr "No puede seleccionar la misma respuesta más de una vez"
-
-#. module: survey
-#: selection:survey.print,paper_size:0
-#: selection:survey.print.answer,paper_size:0
-msgid "Legal (8.5\" x 14\")"
-msgstr "Legal (8.5\" x 14\")"
-
-#. module: survey
-#: field:survey.type,name:0
-msgid "Name"
-msgstr "Nombre"
-
-#. module: survey
-#: view:survey.page:0
-msgid "#Questions"
-msgstr "#Preguntas"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_response
-msgid "survey.response"
-msgstr "encuesta.respuesta"
-
-#. module: survey
-#: field:survey.question,comment_valid_err_msg:0
-#: field:survey.question,make_comment_field_err_msg:0
-#: field:survey.question,numeric_required_sum_err_msg:0
-#: field:survey.question,validation_valid_err_msg:0
-msgid "Error message"
-msgstr "Mensaje de error"
-
-#. module: survey
-#: model:ir.module.module,shortdesc:survey.module_meta_information
-msgid "Survey Module"
-msgstr "Módulo encuestas"
-
-#. module: survey
-#: view:survey.send.invitation:0
-#: field:survey.send.invitation,send_mail:0
-msgid "Send Mail for New User"
-msgstr "Enviar email para nuevo usuario"
-
-#. module: survey
-#: code:addons/survey/survey.py:387
-#, python-format
-msgid "You must enter one or more Answer."
-msgstr "Debe introducir una o más respuestas"
-
-#. module: survey
-#: code:addons/survey/survey.py:416
-#, python-format
-msgid ""
-"Minimum Required Answer you entered is "
-"greater than the number of answer. Please "
-"use a number that is smaller than %d."
-msgstr ""
-"El mínimo de respuestas requeridas que ha introducido es mayor que el número "
-"de respuestas. Por favor, use un número menor que %d."
-
-#. module: survey
-#: field:survey.answer,menu_choice:0
-msgid "Menu Choices"
-msgstr "Opciones de menú"
-
-#. module: survey
-#: field:survey,page_ids:0
-#: view:survey.question:0
-#: field:survey.response.line,page_id:0
-msgid "Page"
-msgstr "Página"
-
-#. module: survey
-#: code:addons/survey/survey.py:438
-#, python-format
-msgid ""
-"Maximum Required Answer is greater than "
-"Minimum Required Answer"
-msgstr ""
-"El máximo de respuestas requeridas es menor que el mínimo de respuestas "
-"requeridas"
-
-#. module: survey
-#: view:survey.send.invitation.log:0
-msgid "User creation"
-msgstr "Creación usuario"
-
-#. module: survey
-#: selection:survey.question,required_type:0
-msgid "All"
-msgstr "Todos"
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Must Be An Email Address"
-msgstr "Debe ser una dirección de email"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Multiple Choice (Only One Answer)"
-msgstr "Selección múltiple (sólo una respuesta)"
-
-#. module: survey
-#: field:survey.answer,in_visible_answer_type:0
-msgid "Is Answer Type Invisible??"
-msgstr "¿El tipo de respuesta es invisible?"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_print_answer
-msgid "survey.print.answer"
-msgstr "encuesta.imprimir.respuesta"
-
-#. module: survey
-#: view:survey.answer:0
-msgid "Menu Choices (each choice on separate by lines)"
-msgstr "Opciones de menú (cada opción en líneas separadas)"
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Float"
-msgstr "Número flotante"
-
-#. module: survey
-#: view:survey.response.line:0
-msgid "Single Textboxes"
-msgstr "Campos de texto únicos"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_send_invitation.py:74
-#, python-format
-msgid "%sSurvey is not in open state"
-msgstr "%s encuesta no está en estado abierto"
-
-#. module: survey
-#: field:survey.question.column.heading,rating_weight:0
-msgid "Weight"
-msgstr "Peso"
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Date & Time"
-msgstr "Fecha y hora"
-
-#. module: survey
-#: field:survey.response,date_create:0
-#: field:survey.response.line,date_create:0
-msgid "Create Date"
-msgstr "Fecha creación"
-
-#. module: survey
-#: field:survey.question,column_name:0
-msgid "Column Name"
-msgstr "Nombre de columna"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_survey_page_form
-#: model:ir.model,name:survey.model_survey_page
-#: model:ir.ui.menu,name:survey.menu_survey_page_form1
-#: view:survey.page:0
-msgid "Survey Pages"
-msgstr "Páginas encuesta"
-
-#. module: survey
-#: field:survey.question,numeric_required_sum:0
-msgid "Sum of all choices"
-msgstr "Suma de todas las elecciones"
-
-#. module: survey
-#: selection:survey.question,type:0
-#: view:survey.response.line:0
-msgid "Table"
-msgstr "Tabla"
-
-#. module: survey
-#: code:addons/survey/survey.py:642
-#, python-format
-msgid "You cannot duplicate the resource!"
-msgstr "¡No puede duplicar el recurso!"
-
-#. module: survey
-#: field:survey.question,comment_minimum_date:0
-#: field:survey.question,validation_minimum_date:0
-msgid "Minimum date"
-msgstr "Fecha mínima"
-
-#. module: survey
-#: field:survey,response_user:0
-msgid "Maximum Answer per User"
-msgstr "Máximas respuestas por usuario"
-
-#. module: survey
-#: field:survey.name.wiz,page:0
-msgid "Page Position"
-msgstr "Posición página"
-
-#~ msgid "All Questions"
-#~ msgstr "Todas las preguntas"
-
-#~ msgid "Give Survey Response"
-#~ msgstr "Responder la encuesta"
-
-#~ msgid "Invalid model name in the action definition."
-#~ msgstr "Nombre de modelo inválido en la definición de acción."
-
-#~ msgid "Survey Analysis Report"
-#~ msgstr "Informe de análisis de encuestas"
-
-#~ msgid "Total Response"
-#~ msgstr "Respuesta total"
-
-#~ msgid "Set to one if you require only one response per user"
-#~ msgstr "Establecer a uno si sólo necesita una respuesta por usuario"
-
-#~ msgid "Users Details"
-#~ msgstr "Detalles usuarios"
-
-#~ msgid "Partner"
-#~ msgstr "Empresa"
-
-#~ msgid "Skip"
-#~ msgstr "Saltar"
-
-#~ msgid "New Survey Question"
-#~ msgstr "Nueva pregunta de encuesta"
-
-#~ msgid "Maximum Response Limit"
-#~ msgstr "Límite respuesta máxima"
-
-#~ msgid "Invalid XML for View Architecture!"
-#~ msgstr "¡XML no válido para la estructura de la vista!"
-
-#~ msgid ""
-#~ "The Object name must start with x_ and not contain any special character !"
-#~ msgstr ""
-#~ "¡El nombre del objeto debe empezar con x_ y no contener ningún carácter "
-#~ "especial!"
-
-#~ msgid "Configuration"
-#~ msgstr "Configuración"
-
-#~ msgid "_Ok"
-#~ msgstr "_Aceptar"
-
-#~ msgid "Page :-"
-#~ msgstr "Página :-"
-
-#~ msgid "#Response"
-#~ msgstr "#Respuesta"
-
-#~ msgid "Response Summary"
-#~ msgstr "Resumen respuesta"
-
-#~ msgid "Response Type"
-#~ msgstr "Tipo respuesta"
-
-#, python-format
-#~ msgid "Error !"
-#~ msgstr "¡Error!"
-
-#~ msgid "New Survey"
-#~ msgstr "Nueva encuesta"
-
-#~ msgid "Response"
-#~ msgstr "Respuesta"
-
-#~ msgid "Modify Date"
-#~ msgstr "Fecha modificada"
-
-#~ msgid "Answered Question"
-#~ msgstr "Pregunta respondida"
-
-#~ msgid "All Surveys"
-#~ msgstr "Todas las encuentas"
-
-#~ msgid ""
-#~ "\n"
-#~ " This module is used for surveing. It depends on the answers or reviews "
-#~ "of some questions by different users.\n"
-#~ " A survey may have multiple pages. Each page may contain multiple "
-#~ "questions and each question may have multiple answers.\n"
-#~ " Different users may give different answers of question and according to "
-#~ "that survey is done. \n"
-#~ " Partners are also sent mails with user name and password for the "
-#~ "invitation of the survey\n"
-#~ " "
-#~ msgstr ""
-#~ "\n"
-#~ " Este módulo es utilizado para realizar encuestas. Depende de las "
-#~ "respuestas o revisión de alguna preguntas por distintos usuarios\n"
-#~ " Una encuesta puede tener múltiples páginas. Cada página puede contener "
-#~ "distintas preguntas y cada pregunta puede tener múltiples respuestas.\n"
-#~ " Distintos usuarios pueden dar distintas respuestas a las preguntas en "
-#~ "función de la encuesta realizada \n"
-#~ " También se pueden enviar correos a las empresas con nombre de usuario y "
-#~ "password con una invitación a realizar la encuesta.\n"
-#~ " "
-
-#~ msgid "All Survey Questions"
-#~ msgstr "Todas las preguntas de encuestas"
-
-#~ msgid "All Survey Pages"
-#~ msgstr "Todas páginas de encuesta"
-
-#~ msgid "Total Started Survey :-"
-#~ msgstr "Total encuestas iniciadas :-"
-
-#~ msgid "Survey Management"
-#~ msgstr "Gestión de encuestas"
-
-#~ msgid "Survey Response"
-#~ msgstr "Respuesta encuesta"
-
-#, python-format
-#~ msgid "'\" + que_rec[0]['question'] + \"' This question requires an answer."
-#~ msgstr ""
-#~ "Copy text \t\r\n"
-#~ "'\" + que_rec[0]['question'] + \"' Esta pregunta requiere una respuesta"
-
-#~ msgid "New Survey Page"
-#~ msgstr "Nueva página de encuesta"
-
-#~ msgid "Survey Title :-"
-#~ msgstr "Título encuesta :-"
-
-#~ msgid "Response Percentage"
-#~ msgstr "Porcentaje respuesta"
-
-#~ msgid "%"
-#~ msgstr "%"
-
-#~ msgid "Total Completed Survey :-"
-#~ msgstr "Total encuesta completada :-"
-
-#, python-format
-#~ msgid "Attention!"
-#~ msgstr "¡Atención!"
-
-#~ msgid "Response Count"
-#~ msgstr "Cuenta respuestas"
-
-#~ msgid "Maximum Response per User"
-#~ msgstr "Máximas respuestas por usuario"
diff --git a/addons/survey/i18n/es_VE.po b/addons/survey/i18n/es_VE.po
deleted file mode 100644
index 7c1c9bbbad1..00000000000
--- a/addons/survey/i18n/es_VE.po
+++ /dev/null
@@ -1,1914 +0,0 @@
-# Spanish translation for openobject-addons
-# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
-# This file is distributed under the same license as the openobject-addons package.
-# FIRST AUTHOR , 2010.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: openobject-addons\n"
-"Report-Msgid-Bugs-To: FULL NAME \n"
-"POT-Creation-Date: 2011-01-11 11:16+0000\n"
-"PO-Revision-Date: 2011-01-18 18:43+0000\n"
-"Last-Translator: Jordi Esteve (www.zikzakmedia.com) "
-"\n"
-"Language-Team: Spanish \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-09-05 05:45+0000\n"
-"X-Generator: Launchpad (build 13830)\n"
-
-#. module: survey
-#: view:survey.print:0
-#: view:survey.print.answer:0
-msgid "Print Option"
-msgstr "Opción imprimir"
-
-#. module: survey
-#: code:addons/survey/survey.py:422
-#, python-format
-msgid ""
-"Minimum Required Answer you entered is "
-"greater than the number of answer. "
-"Please use a number that is smaller than %d."
-msgstr ""
-"El número mínimo de respuestas requeridas que ha introducido es mayor que el "
-"número de respuestas. Por favor, use un número menor que %d."
-
-#. module: survey
-#: view:survey.question.wiz:0
-msgid "Your Messages"
-msgstr "Sus mensajes"
-
-#. module: survey
-#: field:survey.question,comment_valid_type:0
-#: field:survey.question,validation_type:0
-msgid "Text Validation"
-msgstr "Validación del texto"
-
-#. module: survey
-#: code:addons/survey/survey.py:434
-#, python-format
-msgid ""
-"Maximum Required Answer you entered for "
-"your maximum is greater than the number of answer. "
-" Please use a number that is smaller than %d."
-msgstr ""
-"El número máximo de respuestas requeridas que ha introducido para su máximo "
-"es mayor que el número de respuestas. Por favor, use un número menor que %d."
-
-#. module: survey
-#: view:survey:0
-#: field:survey,invited_user_ids:0
-msgid "Invited User"
-msgstr "Usuario invitado"
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Character"
-msgstr "Carácter"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_survey_form1
-#: model:ir.ui.menu,name:survey.menu_print_survey_form
-#: model:ir.ui.menu,name:survey.menu_reporting
-#: model:ir.ui.menu,name:survey.menu_survey_form
-#: model:ir.ui.menu,name:survey.menu_surveys
-msgid "Surveys"
-msgstr "Encuestas"
-
-#. module: survey
-#: view:survey:0
-msgid "Set to draft"
-msgstr "Cambiar a borrador"
-
-#. module: survey
-#: field:survey.question,in_visible_answer_type:0
-msgid "Is Answer Type Invisible?"
-msgstr "¿La respuesta es de tipo invisible?"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-#: view:survey.request:0
-msgid "Group By..."
-msgstr "Agrupar por..."
-
-#. module: survey
-#: view:survey.send.invitation.log:0
-msgid "Results :"
-msgstr "Resultados :"
-
-#. module: survey
-#: view:survey.request:0
-msgid "Survey Request"
-msgstr "Solicitud de encuesta"
-
-#. module: survey
-#: selection:survey.question,required_type:0
-msgid "A Range"
-msgstr "Un rango"
-
-#. module: survey
-#: view:survey.response.line:0
-msgid "Table Answer"
-msgstr "Tabla de respuesta"
-
-#. module: survey
-#: field:survey.history,date:0
-msgid "Date started"
-msgstr "Fecha de inicio"
-
-#. module: survey
-#: field:survey,history:0
-msgid "History Lines"
-msgstr "Líneas histórico"
-
-#. module: survey
-#: code:addons/survey/survey.py:448
-#, python-format
-msgid ""
-"You must enter one or more menu choices in "
-"column heading (white spaces not allowed)"
-msgstr ""
-"Debe introducir una o más opciones de menú en la cabecera de columna (no se "
-"permiten espacios en blanco)"
-
-#. module: survey
-#: field:survey.question.column.heading,in_visible_menu_choice:0
-msgid "Is Menu Choice Invisible??"
-msgstr "¿La opción de menú es invisible?"
-
-#. module: survey
-#: field:survey.send.invitation,mail:0
-msgid "Body"
-msgstr "Cuerpo"
-
-#. module: survey
-#: field:survey.question,allow_comment:0
-msgid "Allow Comment Field"
-msgstr "Permitir campo comentario"
-
-#. module: survey
-#: selection:survey.print,paper_size:0
-#: selection:survey.print.answer,paper_size:0
-msgid "A4 (210mm x 297mm)"
-msgstr "A4 (210mm x 297mm)"
-
-#. module: survey
-#: field:survey.question,comment_maximum_date:0
-#: field:survey.question,validation_maximum_date:0
-msgid "Maximum date"
-msgstr "Fecha Máxima"
-
-#. module: survey
-#: field:survey.question,in_visible_menu_choice:0
-msgid "Is Menu Choice Invisible?"
-msgstr "¿La opción de menú es invisible?"
-
-#. module: survey
-#: view:survey:0
-msgid "Completed"
-msgstr "Completada"
-
-#. module: survey
-#: selection:survey.question,required_type:0
-msgid "Exactly"
-msgstr "Exactamente"
-
-#. module: survey
-#: view:survey:0
-msgid "Open Date"
-msgstr "Fecha de Inicio"
-
-#. module: survey
-#: view:survey.request:0
-msgid "Set to Draft"
-msgstr "Cambiar a borrador"
-
-#. module: survey
-#: field:survey.question,is_comment_require:0
-msgid "Add Comment Field"
-msgstr "Campo para agregar comentario"
-
-#. module: survey
-#: code:addons/survey/survey.py:401
-#, python-format
-msgid ""
-"#Required Answer you entered is greater "
-"than the number of answer. Please use a "
-"number that is smaller than %d."
-msgstr ""
-"Número de respuestas requeridas que ha escrito es mayor que el número de "
-"respuestas. Introduzca un número menor que %d."
-
-#. module: survey
-#: field:survey.question,tot_resp:0
-msgid "Total Answer"
-msgstr "Total respuesta"
-
-#. module: survey
-#: field:survey.tbl.column.heading,name:0
-msgid "Row Number"
-msgstr "Número de Fila"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_name_wiz
-msgid "survey.name.wiz"
-msgstr "encuesta.nombre.asist"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_survey_question_form
-msgid "Survey Questions"
-msgstr "Preguntas de las encuestas"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Matrix of Choices (Only One Answers Per Row)"
-msgstr "Matriz de selección (solamente una respuesta por fila)"
-
-#. module: survey
-#: code:addons/survey/survey.py:475
-#, python-format
-msgid ""
-"Maximum Required Answer you entered for your maximum is greater than the "
-"number of answer. Please use a number that is smaller than %d."
-msgstr ""
-"El número máximo de respuestas requeridas que ha introducido para su máximo "
-"es mayor que el número de respuestas. Por favor, use un número menor que %d."
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_question_message
-#: model:ir.model,name:survey.model_survey_question
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Survey Question"
-msgstr "Pregunta de la encuesta"
-
-#. module: survey
-#: view:survey.question.column.heading:0
-msgid "Use if question type is rating_scale"
-msgstr "Utilizar si la pregunta es de tipo calificación_escala"
-
-#. module: survey
-#: field:survey.print,page_number:0
-#: field:survey.print.answer,page_number:0
-msgid "Include Page Number"
-msgstr "Incluir número de página"
-
-#. module: survey
-#: view:survey.page:0
-#: view:survey.question:0
-#: view:survey.send.invitation.log:0
-msgid "Ok"
-msgstr "Aceptar"
-
-#. module: survey
-#: field:survey.page,title:0
-msgid "Page Title"
-msgstr "Título de la página"
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_define_survey
-msgid "Define Surveys"
-msgstr "Definir encuestas"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_history
-msgid "Survey History"
-msgstr "Histórico encuestas"
-
-#. module: survey
-#: field:survey.response.answer,comment:0
-#: field:survey.response.line,comment:0
-msgid "Notes"
-msgstr "Notas"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.request:0
-msgid "Search Survey"
-msgstr "Buscar encuesta"
-
-#. module: survey
-#: field:survey.response.answer,answer:0
-#: field:survey.tbl.column.heading,value:0
-msgid "Value"
-msgstr "Valor"
-
-#. module: survey
-#: field:survey.question,column_heading_ids:0
-msgid " Column heading"
-msgstr " Cabecera columna"
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_run_survey_form
-msgid "Answer a Survey"
-msgstr "Responder una encuesta"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:92
-#, python-format
-msgid "Error!"
-msgstr "¡Error!"
-
-#. module: survey
-#: field:survey,tot_comp_survey:0
-msgid "Total Completed Survey"
-msgstr "Total encuestas completadas"
-
-#. module: survey
-#: view:survey.response.answer:0
-msgid "(Use Only Question Type is matrix_of_drop_down_menus)"
-msgstr "(usar sólo cuando el tipo de pregunta sea matrix_of_drop_down_menus)"
-
-#. module: survey
-#: model:ir.actions.report.xml,name:survey.survey_analysis
-msgid "Survey Statistics"
-msgstr "Estadísticas encuestas"
-
-#. module: survey
-#: selection:survey,state:0
-#: view:survey.request:0
-#: selection:survey.request,state:0
-msgid "Cancelled"
-msgstr "Cancelada"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Rating Scale"
-msgstr "Escala de calificación"
-
-#. module: survey
-#: field:survey.question,comment_field_type:0
-msgid "Comment Field Type"
-msgstr "Campo tipo comentario"
-
-#. module: survey
-#: code:addons/survey/survey.py:375
-#: code:addons/survey/survey.py:387
-#: code:addons/survey/survey.py:401
-#: code:addons/survey/survey.py:406
-#: code:addons/survey/survey.py:416
-#: code:addons/survey/survey.py:422
-#: code:addons/survey/survey.py:428
-#: code:addons/survey/survey.py:434
-#: code:addons/survey/survey.py:438
-#: code:addons/survey/survey.py:444
-#: code:addons/survey/survey.py:448
-#: code:addons/survey/survey.py:458
-#: code:addons/survey/survey.py:462
-#: code:addons/survey/survey.py:467
-#: code:addons/survey/survey.py:473
-#: code:addons/survey/survey.py:475
-#: code:addons/survey/survey.py:477
-#: code:addons/survey/survey.py:482
-#: code:addons/survey/survey.py:484
-#: code:addons/survey/survey.py:642
-#: code:addons/survey/wizard/survey_answer.py:124
-#: code:addons/survey/wizard/survey_answer.py:131
-#: code:addons/survey/wizard/survey_answer.py:700
-#: code:addons/survey/wizard/survey_answer.py:739
-#: code:addons/survey/wizard/survey_answer.py:759
-#: code:addons/survey/wizard/survey_answer.py:788
-#: code:addons/survey/wizard/survey_answer.py:793
-#: code:addons/survey/wizard/survey_answer.py:801
-#: code:addons/survey/wizard/survey_answer.py:812
-#: code:addons/survey/wizard/survey_answer.py:821
-#: code:addons/survey/wizard/survey_answer.py:826
-#: code:addons/survey/wizard/survey_answer.py:900
-#: code:addons/survey/wizard/survey_answer.py:936
-#: code:addons/survey/wizard/survey_answer.py:954
-#: code:addons/survey/wizard/survey_answer.py:982
-#: code:addons/survey/wizard/survey_answer.py:985
-#: code:addons/survey/wizard/survey_answer.py:988
-#: code:addons/survey/wizard/survey_answer.py:1000
-#: code:addons/survey/wizard/survey_answer.py:1007
-#: code:addons/survey/wizard/survey_answer.py:1010
-#: code:addons/survey/wizard/survey_selection.py:134
-#: code:addons/survey/wizard/survey_selection.py:138
-#: code:addons/survey/wizard/survey_send_invitation.py:74
-#, python-format
-msgid "Warning !"
-msgstr "¡ Advertencia !"
-
-#. module: survey
-#: selection:survey.question,comment_field_type:0
-msgid "Single Line Of Text"
-msgstr "Única línea de texto"
-
-#. module: survey
-#: view:survey.send.invitation:0
-#: field:survey.send.invitation,send_mail_existing:0
-msgid "Send Reminder for Existing User"
-msgstr "Enviar recordatorio para usuario existente"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Multiple Choice (Multiple Answer)"
-msgstr "Selección múltiple (mútiples respuestas)"
-
-#. module: survey
-#: view:survey:0
-msgid "Edit Survey"
-msgstr "Editar encuesta"
-
-#. module: survey
-#: view:survey.response.line:0
-msgid "Survey Answer Line"
-msgstr "Líne de respuesta encuesta"
-
-#. module: survey
-#: field:survey.question.column.heading,menu_choice:0
-msgid "Menu Choice"
-msgstr "Selección Menú"
-
-#. module: survey
-#: selection:survey.question,required_type:0
-msgid "At Most"
-msgstr "Como máximo"
-
-#. module: survey
-#: field:survey.question,is_validation_require:0
-msgid "Validate Text"
-msgstr "Validar texto"
-
-#. module: survey
-#: field:survey.response.line,single_text:0
-msgid "Text"
-msgstr "Texto"
-
-#. module: survey
-#: constraint:res.users:0
-msgid "The chosen company is not in the allowed companies for this user"
-msgstr ""
-"La compañía seleccionada no está en las compañías permitidas para este "
-"usuario"
-
-#. module: survey
-#: selection:survey.print,paper_size:0
-#: selection:survey.print.answer,paper_size:0
-msgid "Letter (8.5\" x 11\")"
-msgstr "Carta (8.5\" x 11\")"
-
-#. module: survey
-#: view:survey:0
-#: field:survey,responsible_id:0
-msgid "Responsible"
-msgstr "Responsable"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_request
-msgid "survey.request"
-msgstr "solicitud.encuesta"
-
-#. module: survey
-#: field:survey.send.invitation,mail_subject:0
-#: field:survey.send.invitation,mail_subject_existing:0
-msgid "Subject"
-msgstr "Asunto"
-
-#. module: survey
-#: field:survey.question,comment_maximum_float:0
-#: field:survey.question,validation_maximum_float:0
-msgid "Maximum decimal number"
-msgstr "Máximo número de decimales"
-
-#. module: survey
-#: view:survey.request:0
-msgid "Late"
-msgstr "Retrasado"
-
-#. module: survey
-#: sql_constraint:res.users:0
-msgid "You can not have two users with the same login !"
-msgstr "¡No puede tener dos usuarios con el mismo identificador de usuario!"
-
-#. module: survey
-#: field:survey.send.invitation,mail_from:0
-msgid "From"
-msgstr "De"
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Don't Validate Comment Text."
-msgstr "No validar texto de comentario"
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Must Be A Whole Number"
-msgstr "Debe ser un número entero"
-
-#. module: survey
-#: field:survey.answer,question_id:0
-#: field:survey.page,question_ids:0
-#: field:survey.question,question:0
-#: field:survey.question.column.heading,question_id:0
-#: field:survey.response.line,question_id:0
-msgid "Question"
-msgstr "Pregunta"
-
-#. module: survey
-#: view:survey.page:0
-msgid "Search Survey Page"
-msgstr "Buscar página de la encuesta"
-
-#. module: survey
-#: view:survey.send.invitation:0
-msgid "Send"
-msgstr "Enviar"
-
-#. module: survey
-#: field:survey.question.wiz,name:0
-msgid "Number"
-msgstr "Número"
-
-#. module: survey
-#: code:addons/survey/survey.py:444
-#, python-format
-msgid ""
-"You must enter one or more menu choices in "
-"column heading"
-msgstr ""
-"Debe introducir una o más opciones de menú en el encabezado de la columna"
-
-#. module: survey
-#: model:ir.actions.act_window,help:survey.action_survey_form1
-msgid ""
-"You can create survey for different purposes: recruitment interviews, "
-"employee's periodical evaluations, marketing campaigns, etc. A survey is "
-"made of pages containing questions of several types: text, multiple choices, "
-"etc. You can edit survey manually or click on the 'Edit Survey' for a "
-"WYSIWYG interface."
-msgstr ""
-"Puede crear encuestas para diferentes propósitos: entrevistas de selección "
-"de personal, evaluaciones periódicas de los empleados, campañas de "
-"marketing, etc. Una encuesta se compone de páginas que contienen preguntas "
-"de varios tipos: texto, opciones múltiples, etc. Puede editar la encuesta "
-"manualmente o hacer clic en \"Editar encuesta” para una interfaz WYSIWYG."
-
-#. module: survey
-#: view:survey:0
-#: view:survey.request:0
-#: field:survey.request,state:0
-msgid "State"
-msgstr "Estado"
-
-#. module: survey
-#: view:survey.request:0
-msgid "Evaluation Plan Phase"
-msgstr "Fase del plan de evaluación"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Between"
-msgstr "Entre"
-
-#. module: survey
-#: view:survey.print:0
-#: view:survey.print.answer:0
-#: view:survey.print.statistics:0
-msgid "Print"
-msgstr "Imprimir"
-
-#. module: survey
-#: field:survey.question,make_comment_field:0
-msgid "Make Comment Field an Answer Choice"
-msgstr "Hacer campo comentario como opción de respuesta"
-
-#. module: survey
-#: view:survey:0
-#: field:survey,type:0
-msgid "Type"
-msgstr "Tipo"
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Email"
-msgstr "Email"
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_answer_surveys
-msgid "Answer Surveys"
-msgstr "Reponder encuestas"
-
-#. module: survey
-#: selection:survey.response,state:0
-msgid "Not Finished"
-msgstr "No teminado"
-
-#. module: survey
-#: view:survey.print:0
-msgid "Survey Print"
-msgstr "Imprimir encuesta"
-
-#. module: survey
-#: view:survey.send.invitation:0
-msgid "Select Partner"
-msgstr "Seleccionar empresa"
-
-#. module: survey
-#: field:survey.question,type:0
-msgid "Question Type"
-msgstr "Tipo pregunta"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:131
-#, python-format
-msgid "You can not answer this survey more than %s times"
-msgstr "No puede responder a esta encuesta más de '%s' veces"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.act_survey_answer
-msgid "Answers"
-msgstr "Respuestas"
-
-#. module: survey
-#: model:ir.module.module,description:survey.module_meta_information
-msgid ""
-"\n"
-" This module is used for surveying. It depends on the answers or reviews "
-"of some questions by different users.\n"
-" A survey may have multiple pages. Each page may contain multiple "
-"questions and each question may have multiple answers.\n"
-" Different users may give different answers of question and according to "
-"that survey is done. \n"
-" Partners are also sent mails with user name and password for the "
-"invitation of the survey\n"
-" "
-msgstr ""
-"\n"
-" Este módulo se usa para realizar encuestas. Se basa en las respuestas o "
-"comentarios de los usuarios a varias preguntas.\n"
-" Una encuesta puede tener varias páginas. Cada página puede contener "
-"múltiples preguntas y cada pregunta puede tener varias respuestas.\n"
-" Diferentes usuarios pueden dar diferentes respuestas a la pregunta de "
-"acuerdo a como esté confeccionada la encuesta.\n"
-" También se puede invitar a las empresas a responder una encuesta, "
-"enviándoles correos electrónicos con nombre de usuario y contraseña.\n"
-" "
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:124
-#, python-format
-msgid "You can not answer because the survey is not open"
-msgstr "No puede responder porque la encuesta no está abierta"
-
-#. module: survey
-#: selection:survey.response,response_type:0
-msgid "Link"
-msgstr "Vínculo"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_survey_type_form
-#: model:ir.model,name:survey.model_survey_type
-#: view:survey.type:0
-msgid "Survey Type"
-msgstr "Tipo de encuesta"
-
-#. module: survey
-#: field:survey.page,sequence:0
-msgid "Page Nr"
-msgstr "Nº página"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-#: field:survey.question,descriptive_text:0
-#: selection:survey.question,type:0
-msgid "Descriptive Text"
-msgstr "Texto descriptivo"
-
-#. module: survey
-#: field:survey.question,minimum_req_ans:0
-msgid "Minimum Required Answer"
-msgstr "Respuesta mínima requerida"
-
-#. module: survey
-#: code:addons/survey/survey.py:484
-#, python-format
-msgid ""
-"You must enter one or more menu choices in column heading (white spaces not "
-"allowed)"
-msgstr ""
-"Debe introducir una o más opciones de menú en el encabezado de la columna "
-"(espacios en blanco no está permitidos)"
-
-#. module: survey
-#: field:survey.question,req_error_msg:0
-msgid "Error Message"
-msgstr "Mensaje de error"
-
-#. module: survey
-#: code:addons/survey/survey.py:482
-#, python-format
-msgid "You must enter one or more menu choices in column heading"
-msgstr "Debe introducir una o más opciones de menú en la cabecera de columna"
-
-#. module: survey
-#: field:survey.request,date_deadline:0
-msgid "Deadline date"
-msgstr "Fecha límite"
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Must Be A Date"
-msgstr "Debe ser una fecha"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_print
-msgid "survey.print"
-msgstr "encuesta.imprimir"
-
-#. module: survey
-#: view:survey.question.column.heading:0
-#: field:survey.question.column.heading,title:0
-msgid "Column Heading"
-msgstr "Cabecera columna"
-
-#. module: survey
-#: field:survey.question,is_require_answer:0
-msgid "Require Answer to Question"
-msgstr "Respuesta obligatoria a la pregunta"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_survey_request_tree
-#: model:ir.ui.menu,name:survey.menu_survey_type_form1
-msgid "Survey Requests"
-msgstr "Solicitudes de encuestas"
-
-#. module: survey
-#: code:addons/survey/survey.py:375
-#: code:addons/survey/survey.py:462
-#, python-format
-msgid "You must enter one or more column heading."
-msgstr "Debe introducir una o más cabeceras de columna."
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:759
-#: code:addons/survey/wizard/survey_answer.py:954
-#, python-format
-msgid "Please enter an integer value"
-msgstr "Por favor introduzca un valor numérico entero"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_browse_answer
-msgid "survey.browse.answer"
-msgstr "encuesta.explorar.respuestas"
-
-#. module: survey
-#: selection:survey.question,comment_field_type:0
-msgid "Paragraph of Text"
-msgstr "Párrafo de texto"
-
-#. module: survey
-#: code:addons/survey/survey.py:428
-#, python-format
-msgid ""
-"Maximum Required Answer you entered for "
-"your maximum is greater than the number of answer. "
-" Please use a number that is smaller than %d."
-msgstr ""
-"El número máximo de respuestas requeridas que ha introducido para su máximo "
-"es mayor que el número de respuestas. Por favor, use un número menor que %d."
-
-#. module: survey
-#: view:survey.request:0
-msgid "Watting Answer"
-msgstr "Esperando respuesta"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "When the question is not answered, display this error message:"
-msgstr ""
-"Cuando la respuesta no sea contestada, mostrar este mensaje de error:"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Options"
-msgstr "Opciones"
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_browse_survey_response
-msgid "Browse Answers"
-msgstr "Buscar respuestas"
-
-#. module: survey
-#: field:survey.response.answer,comment_field:0
-#: view:survey.response.line:0
-msgid "Comment"
-msgstr "Comentario"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_answer
-#: model:ir.model,name:survey.model_survey_response_answer
-#: view:survey.answer:0
-#: view:survey.response:0
-#: view:survey.response.answer:0
-#: view:survey.response.line:0
-msgid "Survey Answer"
-msgstr "Respuesta encuesta"
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Selection"
-msgstr "Selección"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_browse_survey_response
-#: view:survey:0
-msgid "Answer Survey"
-msgstr "Responder encuesta"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Comment Field"
-msgstr "Campo comentario"
-
-#. module: survey
-#: selection:survey.response,response_type:0
-msgid "Manually"
-msgstr "Manualmente"
-
-#. module: survey
-#: help:survey,responsible_id:0
-msgid "User responsible for survey"
-msgstr "Usuario responsable de la encuesta."
-
-#. module: survey
-#: field:survey.question,comment_column:0
-msgid "Add comment column in matrix"
-msgstr "Añadir columna de comentarios en la matriz"
-
-#. module: survey
-#: field:survey.answer,response:0
-msgid "#Answer"
-msgstr "#Respuesta"
-
-#. module: survey
-#: field:survey.print,without_pagebreak:0
-#: field:survey.print.answer,without_pagebreak:0
-msgid "Print Without Page Breaks"
-msgstr "Imprimir sin saltos de página"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "When the comment is an invalid format, display this error message"
-msgstr ""
-"Mostrar este mensaje de error cuando el comentario esté en un formato no "
-"válido"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_selection.py:138
-#, python-format
-msgid ""
-"You can not give more response. Please contact the author of this survey for "
-"further assistance."
-msgstr ""
-"No puede dar más respuestas. Póngase en contacto con el autor de esta "
-"encuesta para obtener más ayuda."
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.act_survey_page_question
-#: model:ir.actions.act_window,name:survey.act_survey_question
-msgid "Questions"
-msgstr "Preguntas"
-
-#. module: survey
-#: help:survey,response_user:0
-msgid "Set to one if you require only one Answer per user"
-msgstr "Establecer a uno si sólo requiere una respuesta por usuario."
-
-#. module: survey
-#: field:survey,users:0
-msgid "Users"
-msgstr "Usuarios"
-
-#. module: survey
-#: view:survey.send.invitation:0
-msgid "Message"
-msgstr "Mensaje"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.request:0
-msgid "MY"
-msgstr "MI"
-
-#. module: survey
-#: field:survey.question,maximum_req_ans:0
-msgid "Maximum Required Answer"
-msgstr "Máximas respuestas requeridas"
-
-#. module: survey
-#: field:survey.name.wiz,page_no:0
-msgid "Page Number"
-msgstr "Número de página"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:92
-#, python-format
-msgid "Cannot locate survey for the question wizard!"
-msgstr "¡No se pudo localizar la encuesta para el asistente de preguntas!"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "and"
-msgstr "y"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_print_statistics
-#: view:survey.print.statistics:0
-msgid "Survey Print Statistics"
-msgstr "Imprimir estadísticas de encuestas"
-
-#. module: survey
-#: field:survey.send.invitation.log,note:0
-msgid "Log"
-msgstr "Registro (Log)"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "When the choices do not add up correctly, display this error message"
-msgstr ""
-"Mostrar este mensaje de error cuando las selecciones no totalicen "
-"correctamente"
-
-#. module: survey
-#: field:survey,date_close:0
-msgid "Survey Close Date"
-msgstr "Fecha de cierre encuestas"
-
-#. module: survey
-#: field:survey,date_open:0
-msgid "Survey Open Date"
-msgstr "Fecha apertura de encuesta"
-
-#. module: survey
-#: field:survey.question.column.heading,in_visible_rating_weight:0
-msgid "Is Rating Scale Invisible ??"
-msgstr "¿La escala de calificación es invisible?"
-
-#. module: survey
-#: view:survey.browse.answer:0
-#: view:survey.name.wiz:0
-msgid "Start"
-msgstr "Inicio"
-
-#. module: survey
-#: code:addons/survey/survey.py:477
-#, python-format
-msgid "Maximum Required Answer is greater than Minimum Required Answer"
-msgstr ""
-"El número máximo de respuestas requeridas es mayor que el mínimo de "
-"respuestas requeridas."
-
-#. module: survey
-#: field:survey.question,comment_maximum_no:0
-#: field:survey.question,validation_maximum_no:0
-msgid "Maximum number"
-msgstr "Número máximo"
-
-#. module: survey
-#: selection:survey,state:0
-#: selection:survey.request,state:0
-#: selection:survey.response.line,state:0
-msgid "Draft"
-msgstr "Borrador"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_print_statistics
-msgid "survey.print.statistics"
-msgstr "encuesta.imprimir.estadisticas"
-
-#. module: survey
-#: selection:survey,state:0
-msgid "Closed"
-msgstr "Cerrada"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Matrix of Drop-down Menus"
-msgstr "Matriz de menús desplegables"
-
-#. module: survey
-#: view:survey:0
-#: field:survey.answer,answer:0
-#: field:survey.name.wiz,response:0
-#: view:survey.page:0
-#: view:survey.print.answer:0
-#: field:survey.print.answer,response_ids:0
-#: view:survey.question:0
-#: field:survey.question,answer_choice_ids:0
-#: field:survey.request,response:0
-#: field:survey.response,question_ids:0
-#: field:survey.response.answer,answer_id:0
-#: field:survey.response.answer,response_id:0
-#: view:survey.response.line:0
-#: field:survey.response.line,response_answer_ids:0
-#: field:survey.response.line,response_id:0
-#: field:survey.response.line,response_table_ids:0
-#: field:survey.send.invitation,partner_ids:0
-#: field:survey.tbl.column.heading,response_table_id:0
-msgid "Answer"
-msgstr "Respuesta"
-
-#. module: survey
-#: field:survey,max_response_limit:0
-msgid "Maximum Answer Limit"
-msgstr "Límite máximo de respuesta"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_act_view_survey_send_invitation
-msgid "Send Invitations"
-msgstr "Enviar invitaciones"
-
-#. module: survey
-#: field:survey.name.wiz,store_ans:0
-msgid "Store Answer"
-msgstr "Guardar respuesta"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Date and Time"
-msgstr "Fecha y hora"
-
-#. module: survey
-#: field:survey,state:0
-#: field:survey.response,state:0
-#: field:survey.response.line,state:0
-msgid "Status"
-msgstr "Estado"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_print
-msgid "Print Survey"
-msgstr "Imprimir encuesta"
-
-#. module: survey
-#: field:survey,send_response:0
-msgid "E-mail Notification on Answer"
-msgstr "Email de notificación sobre la respuesta"
-
-#. module: survey
-#: field:survey.response.answer,value_choice:0
-msgid "Value Choice"
-msgstr "Valor selección"
-
-#. module: survey
-#: view:survey:0
-msgid "Started"
-msgstr "Iniciada"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_print_answer
-#: view:survey:0
-#: view:survey.print.answer:0
-msgid "Print Answer"
-msgstr "Imprimir respuesta"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Multiple Textboxes"
-msgstr "Campos de texto múltiples"
-
-#. module: survey
-#: selection:survey.print,orientation:0
-#: selection:survey.print.answer,orientation:0
-msgid "Landscape(Horizontal)"
-msgstr "Horizontal"
-
-#. module: survey
-#: field:survey.question,no_of_rows:0
-msgid "No of Rows"
-msgstr "Nº de columnas"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.name.wiz:0
-msgid "Survey Details"
-msgstr "Detalles encuesta"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Multiple Textboxes With Different Type"
-msgstr "Campos de texto múltiples con tipo diferente"
-
-#. module: survey
-#: view:survey.question.column.heading:0
-msgid "Menu Choices (each choice on separate lines)"
-msgstr "Opciones de menú (cada opción en líneas separadas)"
-
-#. module: survey
-#: field:survey.response,response_type:0
-msgid "Answer Type"
-msgstr "Tipo respuesta"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Validation"
-msgstr "Validación"
-
-#. module: survey
-#: view:survey.request:0
-#: selection:survey.request,state:0
-msgid "Waiting Answer"
-msgstr "Esperando respuesta"
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Must Be A Decimal Number"
-msgstr "Debe ser un número decimal"
-
-#. module: survey
-#: field:res.users,survey_id:0
-msgid "Groups"
-msgstr "Grupos"
-
-#. module: survey
-#: selection:survey.answer,type:0
-#: selection:survey.question,type:0
-msgid "Date"
-msgstr "Fecha"
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Integer"
-msgstr "Entero"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_send_invitation
-msgid "survey.send.invitation"
-msgstr "encuesta.enviar.invitacion"
-
-#. module: survey
-#: field:survey.history,user_id:0
-#: view:survey.request:0
-#: field:survey.request,user_id:0
-#: field:survey.response,user_id:0
-msgid "User"
-msgstr "Usuario"
-
-#. module: survey
-#: field:survey.name.wiz,transfer:0
-msgid "Page Transfer"
-msgstr "Página de transferencia"
-
-#. module: survey
-#: selection:survey.response.line,state:0
-msgid "Skiped"
-msgstr "Omitido"
-
-#. module: survey
-#: field:survey.print,paper_size:0
-#: field:survey.print.answer,paper_size:0
-msgid "Paper Size"
-msgstr "Tamaño del papel"
-
-#. module: survey
-#: field:survey.response.answer,column_id:0
-#: field:survey.tbl.column.heading,column_id:0
-msgid "Column"
-msgstr "Columna"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_tbl_column_heading
-msgid "survey.tbl.column.heading"
-msgstr "encuesta.tbl.columna.cabecera"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_response_line
-msgid "Survey Response Line"
-msgstr "Línea de respuesta de encuesta"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_selection.py:134
-#, python-format
-msgid "You can not give response for this survey more than %s times"
-msgstr "No puede responder esta encuesta más de %s veces"
-
-#. module: survey
-#: model:ir.actions.report.xml,name:survey.report_survey_form
-#: model:ir.model,name:survey.model_survey
-#: view:survey:0
-#: view:survey.browse.answer:0
-#: field:survey.browse.answer,survey_id:0
-#: field:survey.history,survey_id:0
-#: view:survey.name.wiz:0
-#: field:survey.name.wiz,survey_id:0
-#: view:survey.page:0
-#: field:survey.page,survey_id:0
-#: view:survey.print:0
-#: field:survey.print,survey_ids:0
-#: field:survey.print.statistics,survey_ids:0
-#: field:survey.question,survey:0
-#: view:survey.request:0
-#: field:survey.request,survey_id:0
-#: field:survey.response,survey_id:0
-msgid "Survey"
-msgstr "Encuesta"
-
-#. module: survey
-#: field:survey.question,in_visible_rating_weight:0
-msgid "Is Rating Scale Invisible?"
-msgstr "¿La escala de calificación es invisible?"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Numerical Textboxes"
-msgstr "Campos de texto numéricos"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_question_wiz
-msgid "survey.question.wiz"
-msgstr "enquesta.pregunta.asist"
-
-#. module: survey
-#: view:survey:0
-msgid "History"
-msgstr "Historial"
-
-#. module: survey
-#: help:survey.browse.answer,response_id:0
-msgid ""
-"If this field is empty, all answers of the selected survey will be print."
-msgstr ""
-"Si este campo está vacío, se imprimirán todas las respuestas de la encuesta "
-"seleccionada."
-
-#. module: survey
-#: field:survey.type,code:0
-msgid "Code"
-msgstr "Código"
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_print_survey_statistics
-msgid "Surveys Statistics"
-msgstr "Estadísticas de encuestas"
-
-#. module: survey
-#: field:survey.print,orientation:0
-#: field:survey.print.answer,orientation:0
-msgid "Orientation"
-msgstr "Orientación"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.answer:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Seq"
-msgstr "Secuencia"
-
-#. module: survey
-#: field:survey.request,email:0
-msgid "E-mail"
-msgstr "Email"
-
-#. module: survey
-#: field:survey.question,comment_minimum_no:0
-#: field:survey.question,validation_minimum_no:0
-msgid "Minimum number"
-msgstr "Número mínimo"
-
-#. module: survey
-#: field:survey.question,req_ans:0
-msgid "#Required Answer"
-msgstr "Nº de respuestas requeridas"
-
-#. module: survey
-#: field:survey.answer,sequence:0
-#: field:survey.question,sequence:0
-msgid "Sequence"
-msgstr "Secuencia"
-
-#. module: survey
-#: field:survey.question,comment_label:0
-msgid "Field Label"
-msgstr "Etiqueta del campo"
-
-#. module: survey
-#: view:survey:0
-msgid "Other"
-msgstr "Otros"
-
-#. module: survey
-#: view:survey.request:0
-#: selection:survey.request,state:0
-msgid "Done"
-msgstr "Realizado"
-
-#. module: survey
-#: view:survey:0
-msgid "Test Survey"
-msgstr "Probar encuesta"
-
-#. module: survey
-#: field:survey.question,rating_allow_one_column_require:0
-msgid "Allow Only One Answer per Column (Forced Ranking)"
-msgstr "Permitir una sóla respuesta por columna (clasificación forzada)"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.browse.answer:0
-#: view:survey.name.wiz:0
-#: view:survey.print:0
-#: view:survey.print.answer:0
-#: view:survey.print.statistics:0
-#: view:survey.send.invitation:0
-msgid "Cancel"
-msgstr "Cancelar"
-
-#. module: survey
-#: view:survey:0
-msgid "Close"
-msgstr "Cerrar"
-
-#. module: survey
-#: field:survey.question,comment_minimum_float:0
-#: field:survey.question,validation_minimum_float:0
-msgid "Minimum decimal number"
-msgstr "Número decimal mínimo"
-
-#. module: survey
-#: view:survey:0
-#: selection:survey,state:0
-msgid "Open"
-msgstr "Abrir"
-
-#. module: survey
-#: field:survey,tot_start_survey:0
-msgid "Total Started Survey"
-msgstr "Total encuestas empezadas"
-
-#. module: survey
-#: code:addons/survey/survey.py:467
-#, python-format
-msgid ""
-"#Required Answer you entered is greater than the number of answer. Please "
-"use a number that is smaller than %d."
-msgstr ""
-"El número de respuestas requeridas que ha escrito es mayor que el número de "
-"respuestas. Introduzca un número menor que %d."
-
-#. module: survey
-#: help:survey,max_response_limit:0
-msgid "Set to one if survey is answerable only once"
-msgstr "Establecer a uno si la encuesta sólo puede responderse una vez."
-
-#. module: survey
-#: selection:survey.response,state:0
-msgid "Finished "
-msgstr "Terminado "
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_question_column_heading
-msgid "Survey Question Column Heading"
-msgstr "Cabecera de columna de pregunta de encuesta"
-
-#. module: survey
-#: field:survey.answer,average:0
-msgid "#Avg"
-msgstr "#Prom."
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Matrix of Choices (Multiple Answers Per Row)"
-msgstr "Matriz de opciones (múltiples respuestas por fila)"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_name
-msgid "Give Survey Answer"
-msgstr "Responder encuesta"
-
-#. module: survey
-#: model:ir.model,name:survey.model_res_users
-msgid "res.users"
-msgstr "res.usuarios"
-
-#. module: survey
-#: view:survey:0
-msgid "Current"
-msgstr "Actual"
-
-#. module: survey
-#: selection:survey.response.line,state:0
-msgid "Answered"
-msgstr "Contestadas"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:433
-#, python-format
-msgid "Complete Survey Answer"
-msgstr "Respuesta completa de la encuesta"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Comment/Essay Box"
-msgstr "Campo de comentarios/redacción"
-
-#. module: survey
-#: field:survey.answer,type:0
-msgid "Type of Answer"
-msgstr "Tipo de respuesta"
-
-#. module: survey
-#: field:survey.question,required_type:0
-msgid "Respondent must answer"
-msgstr "El encuestado debe responder"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_send_invitation
-#: view:survey.send.invitation:0
-msgid "Send Invitation"
-msgstr "Enviar invitación"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:793
-#, python-format
-msgid "You cannot select the same answer more than one time"
-msgstr "No se puede seleccionar la misma respuesta más de una vez"
-
-#. module: survey
-#: view:survey.question:0
-msgid "Search Question"
-msgstr "Buscar pregunta"
-
-#. module: survey
-#: field:survey,title:0
-msgid "Survey Title"
-msgstr "Título de la encuesta"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Single Textbox"
-msgstr "Campo de texto único"
-
-#. module: survey
-#: field:survey,note:0
-#: field:survey.name.wiz,note:0
-#: view:survey.page:0
-#: field:survey.page,note:0
-#: view:survey.response.line:0
-msgid "Description"
-msgstr "Descripción"
-
-#. module: survey
-#: view:survey.name.wiz:0
-msgid "Select Survey"
-msgstr "Seleccionar encuesta"
-
-#. module: survey
-#: selection:survey.question,required_type:0
-msgid "At Least"
-msgstr "Al menos"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_send_invitation_log
-#: model:ir.model,name:survey.model_survey_send_invitation_log
-msgid "survey.send.invitation.log"
-msgstr "encuesta.enviar.invitacion.registro"
-
-#. module: survey
-#: selection:survey.print,orientation:0
-#: selection:survey.print.answer,orientation:0
-msgid "Portrait(Vertical)"
-msgstr "Retrato (Vertical)"
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Must Be Specific Length"
-msgstr "Debe ser de longitud específica"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: field:survey.question,page_id:0
-msgid "Survey Page"
-msgstr "Página de la encuesta"
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Required Answer"
-msgstr "Respuesta requerida"
-
-#. module: survey
-#: code:addons/survey/survey.py:473
-#, python-format
-msgid ""
-"Minimum Required Answer you entered is greater than the number of answer. "
-"Please use a number that is smaller than %d."
-msgstr ""
-"El mínimo de respuestas requeridas que ha introducido es mayor que el número "
-"de respuestas. Por favor, use un número menor que %d."
-
-#. module: survey
-#: code:addons/survey/survey.py:458
-#, python-format
-msgid "You must enter one or more answer."
-msgstr "Debe dar una o más respuestas."
-
-#. module: survey
-#: model:ir.actions.report.xml,name:survey.survey_browse_response
-#: field:survey.browse.answer,response_id:0
-msgid "Survey Answers"
-msgstr "Respuestas encuesta"
-
-#. module: survey
-#: view:survey.browse.answer:0
-msgid "Select Survey and Related Answer"
-msgstr "Seleccione encuesta y respuesta relacionada"
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_print_survey_answer
-msgid "Surveys Answers"
-msgstr "Respuestas encuestas"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.act_survey_pages
-msgid "Pages"
-msgstr "Páginas"
-
-#. module: survey
-#: code:addons/survey/survey.py:406
-#, python-format
-msgid ""
-"#Required Answer you entered is greater "
-"than the number of answer. Please use a "
-"number that is smaller than %d."
-msgstr ""
-"El número de respuestas requeridas que ha introducido es mayor que el número "
-"de respuestas. Utilice un número menor que %d."
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:985
-#, python-format
-msgid "You cannot select same answer more than one time'"
-msgstr "No puede seleccionar la misma respuesta más de una vez"
-
-#. module: survey
-#: selection:survey.print,paper_size:0
-#: selection:survey.print.answer,paper_size:0
-msgid "Legal (8.5\" x 14\")"
-msgstr "Legal (8.5\" x 14\")"
-
-#. module: survey
-#: field:survey.type,name:0
-msgid "Name"
-msgstr "Nombre"
-
-#. module: survey
-#: view:survey.page:0
-msgid "#Questions"
-msgstr "#Preguntas"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_response
-msgid "survey.response"
-msgstr "encuesta.respuesta"
-
-#. module: survey
-#: field:survey.question,comment_valid_err_msg:0
-#: field:survey.question,make_comment_field_err_msg:0
-#: field:survey.question,numeric_required_sum_err_msg:0
-#: field:survey.question,validation_valid_err_msg:0
-msgid "Error message"
-msgstr "Mensaje de error"
-
-#. module: survey
-#: model:ir.module.module,shortdesc:survey.module_meta_information
-msgid "Survey Module"
-msgstr "Módulo encuestas"
-
-#. module: survey
-#: view:survey.send.invitation:0
-#: field:survey.send.invitation,send_mail:0
-msgid "Send Mail for New User"
-msgstr "Enviar email para nuevo usuario"
-
-#. module: survey
-#: code:addons/survey/survey.py:387
-#, python-format
-msgid "You must enter one or more Answer."
-msgstr "Debe introducir una o más respuestas"
-
-#. module: survey
-#: code:addons/survey/survey.py:416
-#, python-format
-msgid ""
-"Minimum Required Answer you entered is "
-"greater than the number of answer. Please "
-"use a number that is smaller than %d."
-msgstr ""
-"El mínimo de respuestas requeridas que ha introducido es mayor que el número "
-"de respuestas. Por favor, use un número menor que %d."
-
-#. module: survey
-#: field:survey.answer,menu_choice:0
-msgid "Menu Choices"
-msgstr "Opciones de menú"
-
-#. module: survey
-#: field:survey,page_ids:0
-#: view:survey.question:0
-#: field:survey.response.line,page_id:0
-msgid "Page"
-msgstr "Página"
-
-#. module: survey
-#: code:addons/survey/survey.py:438
-#, python-format
-msgid ""
-"Maximum Required Answer is greater than "
-"Minimum Required Answer"
-msgstr ""
-"El máximo de respuestas requeridas es menor que el mínimo de respuestas "
-"requeridas"
-
-#. module: survey
-#: view:survey.send.invitation.log:0
-msgid "User creation"
-msgstr "Creación usuario"
-
-#. module: survey
-#: selection:survey.question,required_type:0
-msgid "All"
-msgstr "Todos"
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Must Be An Email Address"
-msgstr "Debe ser una dirección de email"
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Multiple Choice (Only One Answer)"
-msgstr "Selección múltiple (sólo una respuesta)"
-
-#. module: survey
-#: field:survey.answer,in_visible_answer_type:0
-msgid "Is Answer Type Invisible??"
-msgstr "¿El tipo de respuesta es invisible?"
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_print_answer
-msgid "survey.print.answer"
-msgstr "encuesta.imprimir.respuesta"
-
-#. module: survey
-#: view:survey.answer:0
-msgid "Menu Choices (each choice on separate by lines)"
-msgstr "Opciones de menú (cada opción en líneas separadas)"
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Float"
-msgstr "Número flotante"
-
-#. module: survey
-#: view:survey.response.line:0
-msgid "Single Textboxes"
-msgstr "Campos de texto únicos"
-
-#. module: survey
-#: code:addons/survey/wizard/survey_send_invitation.py:74
-#, python-format
-msgid "%sSurvey is not in open state"
-msgstr "%s encuesta no está en estado abierto"
-
-#. module: survey
-#: field:survey.question.column.heading,rating_weight:0
-msgid "Weight"
-msgstr "Peso"
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Date & Time"
-msgstr "Fecha y hora"
-
-#. module: survey
-#: field:survey.response,date_create:0
-#: field:survey.response.line,date_create:0
-msgid "Create Date"
-msgstr "Fecha creación"
-
-#. module: survey
-#: field:survey.question,column_name:0
-msgid "Column Name"
-msgstr "Nombre de columna"
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_survey_page_form
-#: model:ir.model,name:survey.model_survey_page
-#: model:ir.ui.menu,name:survey.menu_survey_page_form1
-#: view:survey.page:0
-msgid "Survey Pages"
-msgstr "Páginas encuesta"
-
-#. module: survey
-#: field:survey.question,numeric_required_sum:0
-msgid "Sum of all choices"
-msgstr "Suma de todas las elecciones"
-
-#. module: survey
-#: selection:survey.question,type:0
-#: view:survey.response.line:0
-msgid "Table"
-msgstr "Tabla"
-
-#. module: survey
-#: code:addons/survey/survey.py:642
-#, python-format
-msgid "You cannot duplicate the resource!"
-msgstr "¡No puede duplicar el recurso!"
-
-#. module: survey
-#: field:survey.question,comment_minimum_date:0
-#: field:survey.question,validation_minimum_date:0
-msgid "Minimum date"
-msgstr "Fecha mínima"
-
-#. module: survey
-#: field:survey,response_user:0
-msgid "Maximum Answer per User"
-msgstr "Máximas respuestas por usuario"
-
-#. module: survey
-#: field:survey.name.wiz,page:0
-msgid "Page Position"
-msgstr "Posición página"
-
-#~ msgid "All Questions"
-#~ msgstr "Todas las preguntas"
-
-#~ msgid "Give Survey Response"
-#~ msgstr "Responder la encuesta"
-
-#~ msgid "Invalid model name in the action definition."
-#~ msgstr "Nombre de modelo inválido en la definición de acción."
-
-#~ msgid "Survey Analysis Report"
-#~ msgstr "Informe de análisis de encuestas"
-
-#~ msgid "Total Response"
-#~ msgstr "Respuesta total"
-
-#~ msgid "Set to one if you require only one response per user"
-#~ msgstr "Establecer a uno si sólo necesita una respuesta por usuario"
-
-#~ msgid "Users Details"
-#~ msgstr "Detalles usuarios"
-
-#~ msgid "Partner"
-#~ msgstr "Empresa"
-
-#~ msgid "Skip"
-#~ msgstr "Saltar"
-
-#~ msgid "New Survey Question"
-#~ msgstr "Nueva pregunta de encuesta"
-
-#~ msgid "Maximum Response Limit"
-#~ msgstr "Límite respuesta máxima"
-
-#~ msgid "Invalid XML for View Architecture!"
-#~ msgstr "¡XML no válido para la estructura de la vista!"
-
-#~ msgid ""
-#~ "The Object name must start with x_ and not contain any special character !"
-#~ msgstr ""
-#~ "¡El nombre del objeto debe empezar con x_ y no contener ningún carácter "
-#~ "especial!"
-
-#~ msgid "Configuration"
-#~ msgstr "Configuración"
-
-#~ msgid "_Ok"
-#~ msgstr "_Aceptar"
-
-#~ msgid "Page :-"
-#~ msgstr "Página :-"
-
-#~ msgid "#Response"
-#~ msgstr "#Respuesta"
-
-#~ msgid "Response Summary"
-#~ msgstr "Resumen respuesta"
-
-#~ msgid "Response Type"
-#~ msgstr "Tipo respuesta"
-
-#, python-format
-#~ msgid "Error !"
-#~ msgstr "¡Error!"
-
-#~ msgid "New Survey"
-#~ msgstr "Nueva encuesta"
-
-#~ msgid "Response"
-#~ msgstr "Respuesta"
-
-#~ msgid "Modify Date"
-#~ msgstr "Fecha modificada"
-
-#~ msgid "Answered Question"
-#~ msgstr "Pregunta respondida"
-
-#~ msgid "All Surveys"
-#~ msgstr "Todas las encuentas"
-
-#~ msgid ""
-#~ "\n"
-#~ " This module is used for surveing. It depends on the answers or reviews "
-#~ "of some questions by different users.\n"
-#~ " A survey may have multiple pages. Each page may contain multiple "
-#~ "questions and each question may have multiple answers.\n"
-#~ " Different users may give different answers of question and according to "
-#~ "that survey is done. \n"
-#~ " Partners are also sent mails with user name and password for the "
-#~ "invitation of the survey\n"
-#~ " "
-#~ msgstr ""
-#~ "\n"
-#~ " Este módulo es utilizado para realizar encuestas. Depende de las "
-#~ "respuestas o revisión de alguna preguntas por distintos usuarios\n"
-#~ " Una encuesta puede tener múltiples páginas. Cada página puede contener "
-#~ "distintas preguntas y cada pregunta puede tener múltiples respuestas.\n"
-#~ " Distintos usuarios pueden dar distintas respuestas a las preguntas en "
-#~ "función de la encuesta realizada \n"
-#~ " También se pueden enviar correos a las empresas con nombre de usuario y "
-#~ "password con una invitación a realizar la encuesta.\n"
-#~ " "
-
-#~ msgid "All Survey Questions"
-#~ msgstr "Todas las preguntas de encuestas"
-
-#~ msgid "All Survey Pages"
-#~ msgstr "Todas páginas de encuesta"
-
-#~ msgid "Total Started Survey :-"
-#~ msgstr "Total encuestas iniciadas :-"
-
-#~ msgid "Survey Management"
-#~ msgstr "Gestión de encuestas"
-
-#~ msgid "Survey Response"
-#~ msgstr "Respuesta encuesta"
-
-#, python-format
-#~ msgid "'\" + que_rec[0]['question'] + \"' This question requires an answer."
-#~ msgstr ""
-#~ "Copy text \t\r\n"
-#~ "'\" + que_rec[0]['question'] + \"' Esta pregunta requiere una respuesta"
-
-#~ msgid "New Survey Page"
-#~ msgstr "Nueva página de encuesta"
-
-#~ msgid "Survey Title :-"
-#~ msgstr "Título encuesta :-"
-
-#~ msgid "Response Percentage"
-#~ msgstr "Porcentaje respuesta"
-
-#~ msgid "%"
-#~ msgstr "%"
-
-#~ msgid "Total Completed Survey :-"
-#~ msgstr "Total encuesta completada :-"
-
-#, python-format
-#~ msgid "Attention!"
-#~ msgstr "¡Atención!"
-
-#~ msgid "Response Count"
-#~ msgstr "Cuenta respuestas"
-
-#~ msgid "Maximum Response per User"
-#~ msgstr "Máximas respuestas por usuario"
diff --git a/addons/survey/i18n/survey.pot b/addons/survey/i18n/survey.pot
deleted file mode 100644
index b7e9fcbb924..00000000000
--- a/addons/survey/i18n/survey.pot
+++ /dev/null
@@ -1,1719 +0,0 @@
-# Translation of OpenERP Server.
-# This file contains the translation of the following modules:
-# * survey
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: OpenERP Server 7.0alpha\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-12-21 17:06+0000\n"
-"PO-Revision-Date: 2012-12-21 17:06+0000\n"
-"Last-Translator: <>\n"
-"Language-Team: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: \n"
-"Plural-Forms: \n"
-
-#. module: survey
-#: view:survey.response.line:0
-msgid "Single Textboxes"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/survey.py:471
-#, python-format
-msgid "Minimum Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d."
-msgstr ""
-
-#. module: survey
-#: view:survey.question.wiz:0
-msgid "Your Messages"
-msgstr ""
-
-#. module: survey
-#: field:survey.question,comment_valid_type:0
-#: field:survey.question,validation_type:0
-msgid "Text Validation"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-msgid "Answers:"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: field:survey,invited_user_ids:0
-msgid "Invited User"
-msgstr ""
-
-#. module: survey
-#: model:survey.type,name:survey.survey_type1
-msgid "Human Resources"
-msgstr ""
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Character"
-msgstr ""
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_survey_form1
-#: model:ir.ui.menu,name:survey.menu_survey_form
-#: model:ir.ui.menu,name:survey.menu_surveys
-msgid "Surveys"
-msgstr ""
-
-#. module: survey
-#: field:survey.question,in_visible_answer_type:0
-msgid "Is Answer Type Invisible?"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-#: view:survey.request:0
-msgid "Group By..."
-msgstr ""
-
-#. module: survey
-#: view:survey.send.invitation.log:0
-msgid "Results :"
-msgstr ""
-
-#. module: survey
-#: view:survey.request:0
-msgid "Survey Request"
-msgstr ""
-
-#. module: survey
-#: selection:survey.question,required_type:0
-msgid "A Range"
-msgstr ""
-
-#. module: survey
-#: view:survey.response.line:0
-msgid "Table Answer"
-msgstr ""
-
-#. module: survey
-#: field:survey.history,date:0
-msgid "Date started"
-msgstr ""
-
-#. module: survey
-#: field:survey,history:0
-msgid "History Lines"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-#: field:survey.question,descriptive_text:0
-#: selection:survey.question,type:0
-msgid "Descriptive Text"
-msgstr ""
-
-#. module: survey
-#: field:survey.send.invitation,mail:0
-msgid "Body"
-msgstr ""
-
-#. module: survey
-#: field:survey.question,allow_comment:0
-msgid "Allow Comment Field"
-msgstr ""
-
-#. module: survey
-#: selection:survey.print,paper_size:0
-#: selection:survey.print.answer,paper_size:0
-msgid "A4 (210mm x 297mm)"
-msgstr ""
-
-#. module: survey
-#: field:survey.question,comment_maximum_date:0
-#: field:survey.question,validation_maximum_date:0
-msgid "Maximum date"
-msgstr ""
-
-#. module: survey
-#: field:survey.question,in_visible_menu_choice:0
-msgid "Is Menu Choice Invisible?"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-msgid "Completed"
-msgstr ""
-
-#. module: survey
-#: selection:survey.question,required_type:0
-msgid "Exactly"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-msgid "Open Date"
-msgstr ""
-
-#. module: survey
-#: view:survey.request:0
-msgid "Set to Draft"
-msgstr ""
-
-#. module: survey
-#: field:survey.question,is_comment_require:0
-msgid "Add Comment Field"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/survey.py:450
-#, python-format
-msgid "#Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d."
-msgstr ""
-
-#. module: survey
-#: field:survey.question,tot_resp:0
-msgid "Total Answer"
-msgstr ""
-
-#. module: survey
-#: field:survey.tbl.column.heading,name:0
-msgid "Row Number"
-msgstr ""
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_name_wiz
-msgid "survey.name.wiz"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/survey.py:483
-#, python-format
-msgid "Maximum Required Answer you entered for your maximum is greater than the number of answer. Please use a number that is smaller than %d."
-msgstr ""
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Matrix of Choices (Only One Answers Per Row)"
-msgstr ""
-
-#. module: survey
-#: view:survey.send.invitation:0
-#: field:survey.send.invitation,send_mail_existing:0
-msgid "Send Reminder for Existing User"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/survey.py:525
-#, python-format
-msgid "Maximum Required Answer you entered for your maximum is greater than the number of answer. Please use a number that is smaller than %d."
-msgstr ""
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_question
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Survey Question"
-msgstr ""
-
-#. module: survey
-#: view:survey.question.column.heading:0
-msgid "Use if question type is rating_scale"
-msgstr ""
-
-#. module: survey
-#: field:survey.print,page_number:0
-#: field:survey.print.answer,page_number:0
-msgid "Include Page Number"
-msgstr ""
-
-#. module: survey
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Ok"
-msgstr ""
-
-#. module: survey
-#: field:survey.page,title:0
-msgid "Page Title"
-msgstr ""
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_history
-msgid "Survey History"
-msgstr ""
-
-#. module: survey
-#: field:survey.response.answer,comment:0
-#: field:survey.response.line,comment:0
-msgid "Notes"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: view:survey.request:0
-msgid "Search Survey"
-msgstr ""
-
-#. module: survey
-#: field:survey.response.answer,answer:0
-#: field:survey.tbl.column.heading,value:0
-msgid "Value"
-msgstr ""
-
-#. module: survey
-#: field:survey.question,column_heading_ids:0
-msgid " Column heading"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/wizard/survey_send_invitation.py:71
-#, python-format
-msgid "The following surveys are not in open state: %s"
-msgstr ""
-
-#. module: survey
-#: field:survey,tot_comp_survey:0
-msgid "Total Completed Survey"
-msgstr ""
-
-#. module: survey
-#: view:survey.response.answer:0
-msgid "(Use Only Question Type is matrix_of_drop_down_menus)"
-msgstr ""
-
-#. module: survey
-#: model:ir.actions.report.xml,name:survey.survey_analysis
-msgid "Survey Statistics"
-msgstr ""
-
-#. module: survey
-#: selection:survey,state:0
-#: selection:survey.request,state:0
-msgid "Cancelled"
-msgstr ""
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Rating Scale"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/survey.py:152
-#: code:addons/survey/survey.py:187
-#, python-format
-msgid "This survey has no question defined. Please define the questions and answers first."
-msgstr ""
-
-#. module: survey
-#: field:survey.question,comment_field_type:0
-msgid "Comment Field Type"
-msgstr ""
-
-#. module: survey
-#: selection:survey.question,comment_field_type:0
-msgid "Single Line Of Text"
-msgstr ""
-
-#. module: survey
-#: field:survey,date_open:0
-msgid "Survey Open Date"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:800
-#, python-format
-msgid "You cannot select the same answer more than one time."
-msgstr ""
-
-#. module: survey
-#: field:survey,color:0
-msgid "Color Index"
-msgstr ""
-
-#. module: survey
-#: selection:survey.question,type:0
-msgid "Multiple Choice (Multiple Answer)"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-msgid "Edit Survey"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:766
-#: code:addons/survey/wizard/survey_answer.py:961
-#, python-format
-msgid "Please enter an integer value."
-msgstr ""
-
-#. module: survey
-#: field:survey.question.column.heading,menu_choice:0
-msgid "Menu Choice"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/survey.py:493
-#, python-format
-msgid "You must enter one or more menu choices in column heading."
-msgstr ""
-
-#. module: survey
-#: selection:survey.question,required_type:0
-msgid "At Most"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: view:survey.request:0
-msgid "My Survey(s)"
-msgstr ""
-
-#. module: survey
-#: view:survey.response.line:0
-msgid "Survey Answer Line"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/wizard/survey_send_invitation.py:72
-#, python-format
-msgid "\n"
-"Hello %%(name)s, \n"
-"\n"
-"\n"
-"Would you please spent some of your time to fill-in our survey: \n"
-"%s\n"
-"\n"
-"You can access this survey with the following parameters:\n"
-" URL: %s\n"
-" Your login ID: %%(login)s\n"
-"\n"
-" Your password: %%(passwd)s\n"
-"\n"
-"\n"
-"\n"
-"\n"
-"Thanks,"
-msgstr ""
-
-#. module: survey
-#: field:survey.response.line,single_text:0
-msgid "Text"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-msgid "Edit..."
-msgstr ""
-
-#. module: survey
-#: selection:survey.print,paper_size:0
-#: selection:survey.print.answer,paper_size:0
-msgid "Letter (8.5\" x 11\")"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: field:survey,responsible_id:0
-msgid "Responsible"
-msgstr ""
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_request
-msgid "survey.request"
-msgstr ""
-
-#. module: survey
-#: field:survey.send.invitation,mail_subject:0
-#: field:survey.send.invitation,mail_subject_existing:0
-msgid "Subject"
-msgstr ""
-
-#. module: survey
-#: field:survey.question,comment_maximum_float:0
-#: field:survey.question,validation_maximum_float:0
-msgid "Maximum decimal number"
-msgstr ""
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_tbl_column_heading
-msgid "survey.tbl.column.heading"
-msgstr ""
-
-#. module: survey
-#: view:survey.send.invitation:0
-#: field:survey.send.invitation,send_mail:0
-msgid "Send Mail for New User"
-msgstr ""
-
-#. module: survey
-#: field:survey.send.invitation,mail_from:0
-msgid "From"
-msgstr ""
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Don't Validate Comment Text."
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/survey.py:532
-#, python-format
-msgid "You must enter one or more menu choices in column heading."
-msgstr ""
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Must Be A Whole Number"
-msgstr ""
-
-#. module: survey
-#: field:survey.answer,question_id:0
-#: view:survey.question:0
-#: field:survey.question,question:0
-#: field:survey.question.column.heading,question_id:0
-#: field:survey.response.line,question_id:0
-msgid "Question"
-msgstr ""
-
-#. module: survey
-#: view:survey.page:0
-msgid "Search Survey Page"
-msgstr ""
-
-#. module: survey
-#: field:survey.question.wiz,name:0
-msgid "Number"
-msgstr ""
-
-#. module: survey
-#: view:survey.request:0
-msgid "Evaluation Plan Phase"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/wizard/survey_send_invitation.py:185
-#: code:addons/survey/wizard/survey_send_invitation.py:196
-#: code:addons/survey/wizard/survey_send_invitation.py:199
-#, python-format
-msgid "Unknown"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Between"
-msgstr ""
-
-#. module: survey
-#: view:survey.print:0
-#: view:survey.print.answer:0
-#: view:survey.print.statistics:0
-msgid "Print"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-msgid "New"
-msgstr ""
-
-#. module: survey
-#: field:survey.question,make_comment_field:0
-msgid "Make Comment Field an Answer Choice"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: field:survey,type:0
-msgid "Type"
-msgstr ""
-
-#. module: survey
-#: selection:survey.answer,type:0
-#: field:survey.request,email:0
-msgid "Email"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/survey.py:96
-#: code:addons/survey/survey.py:259
-#, python-format
-msgid "%s (copy)"
-msgstr ""
-
-#. module: survey
-#: selection:survey.response,state:0
-msgid "Not Finished"
-msgstr ""
-
-#. module: survey
-#: view:survey.print:0
-msgid "Survey Print"
-msgstr ""
-
-#. module: survey
-#: view:survey.send.invitation:0
-msgid "Select Partner"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/survey.py:527
-#, python-format
-msgid "Maximum Required Answer is greater than Minimum Required Answer."
-msgstr ""
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_reporting
-msgid "Reporting"
-msgstr ""
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.act_survey_answer
-msgid "Answers"
-msgstr ""
-
-#. module: survey
-#: selection:survey.response,response_type:0
-msgid "Link"
-msgstr ""
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_survey_type_form
-#: model:ir.model,name:survey.model_survey_type
-#: view:survey.type:0
-msgid "Survey Type"
-msgstr ""
-
-#. module: survey
-#: field:survey.page,sequence:0
-msgid "Page Nr"
-msgstr ""
-
-#. module: survey
-#: model:ir.ui.menu,name:survey.menu_print_survey_form
-msgid "Print Surveys"
-msgstr ""
-
-#. module: survey
-#: field:survey.question.column.heading,in_visible_menu_choice:0
-msgid "Is Menu Choice Invisible??"
-msgstr ""
-
-#. module: survey
-#: field:survey.question,minimum_req_ans:0
-msgid "Minimum Required Answer"
-msgstr ""
-
-#. module: survey
-#: field:survey.question,req_error_msg:0
-msgid "Error Message"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/wizard/survey_answer.py:124
-#, python-format
-msgid "You cannot answer this survey more than %s times."
-msgstr ""
-
-#. module: survey
-#: field:survey.request,date_deadline:0
-msgid "Deadline date"
-msgstr ""
-
-#. module: survey
-#: selection:survey.question,comment_valid_type:0
-#: selection:survey.question,validation_type:0
-msgid "Must Be A Date"
-msgstr ""
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_print
-msgid "survey.print"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: field:survey.question,page_id:0
-msgid "Survey Page"
-msgstr ""
-
-#. module: survey
-#: view:survey.question.column.heading:0
-#: field:survey.question.column.heading,title:0
-msgid "Column Heading"
-msgstr ""
-
-#. module: survey
-#: field:survey.question,is_require_answer:0
-msgid "Require Answer to Question"
-msgstr ""
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.act_survey_request
-#: model:ir.actions.act_window,name:survey.action_survey_request_tree
-#: model:ir.ui.menu,name:survey.menu_survey_type_form1
-msgid "Survey Requests"
-msgstr ""
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_browse_answer
-msgid "survey.browse.answer"
-msgstr ""
-
-#. module: survey
-#: selection:survey.question,comment_field_type:0
-msgid "Paragraph of Text"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/survey.py:477
-#, python-format
-msgid "Maximum Required Answer you entered for your maximum is greater than the number of answer. Please use a number that is smaller than %d."
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "When the question is not answered, display this error message:"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Options"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/survey.py:436
-#, python-format
-msgid "You must enter one or more Answers for question \"%s\" of page %s."
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-msgid "Delete"
-msgstr ""
-
-#. module: survey
-#: field:survey.response.answer,comment_field:0
-#: view:survey.response.line:0
-msgid "Comment"
-msgstr ""
-
-#. module: survey
-#: model:ir.model,name:survey.model_survey_answer
-#: model:ir.model,name:survey.model_survey_response_answer
-#: view:survey.answer:0
-#: view:survey.response:0
-#: view:survey.response.answer:0
-#: view:survey.response.line:0
-msgid "Survey Answer"
-msgstr ""
-
-#. module: survey
-#: selection:survey.answer,type:0
-msgid "Selection"
-msgstr ""
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_browse_survey_response
-#: view:survey:0
-msgid "Answer Survey"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "Comment Field"
-msgstr ""
-
-#. module: survey
-#: selection:survey.response,response_type:0
-msgid "Manually"
-msgstr ""
-
-#. module: survey
-#: view:survey.send.invitation:0
-msgid "_Send"
-msgstr ""
-
-#. module: survey
-#: help:survey,responsible_id:0
-msgid "User responsible for survey"
-msgstr ""
-
-#. module: survey
-#: field:survey,page_ids:0
-#: view:survey.page:0
-#: view:survey.question:0
-#: field:survey.response.line,page_id:0
-msgid "Page"
-msgstr ""
-
-#. module: survey
-#: field:survey.question,comment_column:0
-msgid "Add comment column in matrix"
-msgstr ""
-
-#. module: survey
-#: field:survey.answer,response:0
-msgid "#Answer"
-msgstr ""
-
-#. module: survey
-#: field:survey.print,without_pagebreak:0
-#: field:survey.print.answer,without_pagebreak:0
-msgid "Print Without Page Breaks"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "When the comment is an invalid format, display this error message"
-msgstr ""
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.act_survey_page_question
-#: model:ir.actions.act_window,name:survey.act_survey_question
-#: field:survey.page,question_ids:0
-msgid "Questions"
-msgstr ""
-
-#. module: survey
-#: help:survey,response_user:0
-msgid "Set to one if you require only one Answer per user"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/survey.py:424
-#: code:addons/survey/survey.py:512
-#, python-format
-msgid "You must enter one or more column headings for question \"%s\" of page %s."
-msgstr ""
-
-#. module: survey
-#: model:ir.model,name:survey.model_res_users
-#: field:survey,users:0
-msgid "Users"
-msgstr ""
-
-#. module: survey
-#: view:survey.send.invitation:0
-msgid "Message"
-msgstr ""
-
-#. module: survey
-#: code:addons/survey/survey.py:497
-#, python-format
-msgid "You must enter one or more menu choices in column heading (white spaces not allowed)."
-msgstr ""
-
-#. module: survey
-#: field:survey.question,maximum_req_ans:0
-msgid "Maximum Required Answer"
-msgstr ""
-
-#. module: survey
-#: field:survey.name.wiz,page_no:0
-msgid "Page Number"
-msgstr ""
-
-#. module: survey
-#: view:survey.print:0
-#: view:survey.print.answer:0
-msgid "Print Option"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "and"
-msgstr ""
-
-#. module: survey
-#: model:ir.actions.act_window,name:survey.action_view_survey_print_statistics
-#: view:survey.print.statistics:0
-msgid "Survey Print Statistics"
-msgstr ""
-
-#. module: survey
-#: field:survey.send.invitation.log,note:0
-msgid "Log"
-msgstr ""
-
-#. module: survey
-#: view:survey:0
-#: view:survey.page:0
-#: view:survey.question:0
-msgid "When the choices do not add up correctly, display this error message"
-msgstr ""
-
-#. module: survey
-#: model:ir.actions.act_window,help:survey.action_survey_form1
-msgid "
\n"
-" Click to create a new survey. \n"
-"
\n"
-" You can create survey for different purposes: recruitment\n"
-" interviews, employee's periodical evaluations, marketing\n"
-" campaigns, etc.\n"
-"
\n"
-" A survey is made of pages containing questions\n"
-" of several types: text, multiple choices, etc.\n"
-"
- """
- for que in page.question_ids:
- rml +="""
-
-
""" + to_xml(tools.ustr(que.question)) + """
-
- """
- cols_widhts = []
-
- if que.type in ['matrix_of_choices_only_one_ans','matrix_of_choices_only_multi_ans']:
- cols_widhts.append(200)
- for col in range(0, len(que.column_heading_ids) + 1):
- cols_widhts.append(float(300 / (len(que.column_heading_ids) + 1)))
- colWidths = ",".join(map(tools.ustr, cols_widhts))
- matrix_ans = [(0,'')]
-
- for col in que.column_heading_ids:
- if col.title not in matrix_ans:
- matrix_ans.append((col.id,col.title))
- rml += """
"""
- for mat_col in range(0, len(matrix_ans)):
- rml+="""
"""
- cr.execute("select count(id), sra.answer_id from survey_response_answer sra \
- where sra.column_id='%s' group by sra.answer_id ", (column.id,))
- res_count = cr.dictfetchall()
- cr.execute("select count(sra.id),sra.value_choice, sra.answer_id, sra.column_id from survey_response_answer sra \
- where sra.column_id='%s' group by sra.value_choice ,sra.answer_id, sra.column_id", (column.id,))
- calc_percantage = cr.dictfetchall()
-
- for ans in que.answer_choice_ids:
- rml += """
""" + to_xml(tools.ustr(ans.answer)) + """
"""
- for mat_col in range(0, len(menu_choices)):
- calc = 0
- response = 0
- for res in res_count:
- if res['answer_id'] == ans.id: response = res['count']
- for per in calc_percantage:
- if ans.id == per['answer_id'] and menu_choices[mat_col] == per['value_choice']:
- calc = per['count']
- percantage = 0.00
-
- if calc and response:
- percantage = round((float(calc)* 100) / response,2)
- if calc:
- rml += """
"""
- for ans in que.answer_choice_ids:
- cr.execute("select answer from survey_response_answer where answer_id=%s group by answer", (ans.id,))
- tot_res = cr.dictfetchall()
- total = 0
- for tot in tot_res:
- total += int(tot['answer'])
- per = 0.00
-
- if len(tot_res):
- per = round((float(total) / len(tot_res)),2)
- rml+="""
- """
-
- elif que.type in ['table']:
- if len(answer) and answer[0].state == "done":
- col_heading = registry['survey.tbl.column.heading']
- cols_widhts = []
- tbl_width = float(_tbl_widths.replace('cm', ''))
- for i in range(0, len(que.column_heading_ids)):
- cols_widhts.append(tbl_width / float(len(que.column_heading_ids)))
- colWidths = "cm,".join(map(tools.ustr, cols_widhts))
- colWidths = colWidths + 'cm'
- matrix_ans = []
- rml +="""
"""
-
- for col in que.column_heading_ids:
- if col.title not in matrix_ans:
- matrix_ans.append(col.title)
- rml += """
""" + to_xml(tools.ustr(col.title)) +"""
"""
- rml += """
"""
- i = 0
-
- for row in range(0, que.no_of_rows):
- if i%2 != 0:
- style = 'tbl_white'
- else:
- style = 'tbl_gainsboro'
- i +=1
- rml += """
"""
- table_data = col_heading.browse(cr, uid, col_heading.search(cr, uid, [('response_table_id', '=', answer[0].id), ('name', '=', row)]))
- for column in matrix_ans:
- value = False
- for col in table_data:
- if column == col.column_id.title:
- value = col.value
- if value:
- rml += """
""" + to_xml(tools.ustr(value)) +"""
"""
- else:
- rml += """
"""
- rml += """
"""
-
- else:
- rml +="""
-
"""+ _('No Answer') + """
- """
-
- elif que.type in ['multiple_choice_only_one_ans','multiple_choice_multiple_ans']:
- if len(answer) and answer[0].state == "done":
- ans_list = []
- for ans in answer[0].response_answer_ids:
- ans_list.append(to_xml(tools.ustr(ans.answer_id.answer)))
- answer_choice=[]
-
- for ans in que['answer_choice_ids']:
- answer_choice.append(to_xml(tools.ustr((ans.answer))))
-
- def divide_list(lst, n):
- return [lst[i::n] for i in range(n)]
-
- divide_list = divide_list(answer_choice,_display_ans_in_rows)
- for lst in divide_list:
- if que.type == 'multiple_choice_multiple_ans':
- if len(lst) <> 0 and len(lst) <> int(round(float(len(answer_choice)) / _display_ans_in_rows, 0)):
- lst.append('')
- if not lst:
- del divide_list[divide_list.index(lst):]
-
- for divide in divide_list:
- a = _divide_columns_for_matrix * len(divide)
- b = float(_tbl_widths.replace('cm', '')) - float(a)
- cols_widhts = []
- for div in range(0, len(divide)):
- cols_widhts.append(float(a / len(divide)))
- cols_widhts.append(float(b / len(divide)))
- colWidths = "cm,".join(map(tools.ustr, cols_widhts))
- colWidths = colWidths +'cm'
- rml += """
"""
-
- for div in range(0, len(divide)):
- if divide[div] != '':
- if que.type == 'multiple_choice_multiple_ans':
- if divide[div] in ans_list:
- rml += """
-
-
-
-
-
""" + divide[div] + """
"""
- else:
- rml+="""
-
-
-
""" + divide[div] + """
"""
- else:
- if divide[div] in ans_list:
- rml += """
-
-
-
-
-
""" + divide[div] + """
"""
- else:
- rml += """
-
-
-
-
-
""" + divide[div] + """
"""
- else:
- rml += """
"""
- rml += """
"""
-
- if que.is_comment_require and answer[0].comment:
- rml += """
-
""" + to_xml(tools.ustr(answer[0].comment)) + """
"""
- else:
- rml += """
-
No Answer
- """
-
- elif que.type in ['multiple_textboxes_diff_type','multiple_textboxes','date','date_and_time','numerical_textboxes','multiple_textboxes_diff_type']:
- if len(answer) and answer[0].state == "done":
- cols_widhts = []
- cols_widhts.append(float(_tbl_widths.replace('cm',''))/2)
- cols_widhts.append(float(_tbl_widths.replace('cm',''))/2)
- colWidths = "cm,".join(map(tools.ustr, cols_widhts))
- colWidths = tools.ustr(colWidths) + 'cm'
- answer_list = {}
-
- for ans in answer[0].response_answer_ids:
- answer_list[ans.answer_id.answer] = ans.answer
- for que_ans in que['answer_choice_ids']:
- if que_ans.answer in answer_list:
- rml += """
-
- """
-
- elif que.type in ['comment']:
- if len(answer) and answer[0].state == "done":
- rml += """
-
""" + to_xml(tools.ustr(answer[0].comment)) + """
- """
- else:
- rml += """
-
No Answer
- """
-
- elif que.type in ['matrix_of_choices_only_one_ans','matrix_of_choices_only_multi_ans', 'rating_scale', 'matrix_of_drop_down_menus']:
- if len(answer) and answer[0].state == "done":
- if que.type in ['matrix_of_choices_only_one_ans', 'rating_scale'] and que.comment_column:
- pass
- cols_widhts = []
- if len(que.column_heading_ids):
- cols_widhts.append(float(_tbl_widths.replace('cm','')) / float(2.0))
- for col in que.column_heading_ids:
- cols_widhts.append(float((float(_tbl_widths.replace('cm','')) / float(2.0)) / len(que.column_heading_ids)))
- else:
- cols_widhts.append(float(_tbl_widths.replace('cm','')))
-
- tmp = 0.0
- sum = 0.0
- i = 0
- if que.type in ['matrix_of_choices_only_one_ans','rating_scale'] and que.comment_column:
- for col in cols_widhts:
- if i == 0:
- cols_widhts[i] = cols_widhts[i] / 2.0
- tmp = cols_widhts[i]
- sum += col
- i += 1
- cols_widhts.append(round(tmp, 2))
- colWidths = "cm,".join(map(tools.ustr, cols_widhts))
- colWidths = colWidths + 'cm'
- matrix_ans = [(0, ''),]
-
- for col in que.column_heading_ids:
- if col.title not in matrix_ans:
- matrix_ans.append((col.id, col.title))
- len_matrix = len(matrix_ans)
- if que.type in ['matrix_of_choices_only_one_ans', 'rating_scale'] and que.comment_column:
- matrix_ans.append((0,que.column_name))
- rml += """
"""
-
- for mat_col in range(0, len(matrix_ans)):
- rml += """
- """
-
- elif que.type in ['multiple_choice_multiple_ans','multiple_choice_only_one_ans']:
- answer = []
- for ans in que.answer_choice_ids:
- answer.append(to_xml(tools.ustr((ans.answer))))
-
- def divide_list(lst, n):
- return [lst[i::n] for i in range(n)]
-
- divide_list = divide_list(answer,_display_ans_in_rows)
- for lst in divide_list:
- if que.type == 'multiple_choice_multiple_ans':
- if len(lst)<>0 and len(lst)<>int(round(float(len(answer))/_display_ans_in_rows,0)):
- lst.append('')
- if not lst:
- del divide_list[divide_list.index(lst):]
- for divide in divide_list:
- a = _divide_columns_for_matrix*len(divide)
- b = float(_tbl_widths.replace('cm','')) - float(a)
- cols_widhts = []
-
- for div in range(0,len(divide)):
- cols_widhts.append(float(a/len(divide)))
- cols_widhts.append(float(b/len(divide)))
- colWidths = "cm,".join(map(tools.ustr, cols_widhts))
- colWidths = colWidths +'cm'
- rml+="""
-
"""
- for div in range(0,len(divide)):
- if divide[div] != '':
- if que.type == 'multiple_choice_multiple_ans':
- rml += """
-
-
-
-
-
-
""" + divide[div] + """
"""
- else:
- rml += """
-
-
-
-
-
-
""" + divide[div] + """
"""
- else:
- rml += """
-
-
"""
- rml += """
-
"""
-
- elif que.type in ['matrix_of_choices_only_one_ans','rating_scale','matrix_of_choices_only_multi_ans','matrix_of_drop_down_menus']:
- if len(que.column_heading_ids):
- cols_widhts.append(float(_tbl_widths.replace('cm',''))/float(2.0))
- for col in que.column_heading_ids:
- cols_widhts.append(float((float(_tbl_widths.replace('cm',''))/float(2.0))/len(que.column_heading_ids)))
- else:
- cols_widhts.append(float(_tbl_widths.replace('cm','')))
-
- tmp = 0.0
- sum = 0.0
- i = 0
- if que.comment_column:
- for col in cols_widhts:
- if i == 0:
- cols_widhts[i] = cols_widhts[i]/2.0
- tmp = cols_widhts[i]
- sum += col
- i += 1
- cols_widhts.append(round(tmp,2))
- colWidths = "cm,".join(map(tools.ustr, cols_widhts))
- colWidths = colWidths+'cm'
- matrix_ans = ['',]
-
- for col in que.column_heading_ids:
- if col.title not in matrix_ans:
- matrix_ans.append(col.title)
- if que.comment_column:
- matrix_ans.append(to_xml(tools.ustr(que.column_name)))
- rml+="""
"""
-
- for mat_col in matrix_ans:
- rml += """
""" + to_xml(tools.ustr(mat_col)) + """
"""
- rml += """
"""
- i = 0
- for ans in que.answer_choice_ids:
- if i%2 != 0:
- style='ans_tbl_white'
- else:
- style='ans_tbl_gainsboro'
- i += 1
- rml += """
-
-
""" + to_xml(tools.ustr(ans.answer)) + """
"""
- rec_width = float((sum-tmp)*10+100)
- value = ""
-
- if que.type in ['matrix_of_drop_down_menus']:
- value = """
- """
- elif que.type in ['matrix_of_choices_only_one_ans','rating_scale']:
- value = """
- """
- else:
- value = """
- """
- for mat_col in range(1,len(matrix_ans)):
- if matrix_ans[mat_col] == que.column_name:
- if mat_col == 1:
- rml += """
-
""" + to_xml(tools.ustr(que.column_name)) + """
"""
- else:
- rml += """
"""
- else:
- rml += """
""" + value + """
"""
- rml += """
"""
-
- elif que.type in ['multiple_textboxes', 'numerical_textboxes', 'date_and_time','date','multiple_textboxes_diff_type']:
- cols_widhts.append(float(_tbl_widths.replace('cm',''))/2)
- cols_widhts.append(float(_tbl_widths.replace('cm',''))/2)
- colWidths = "cm,".join(map(tools.ustr, cols_widhts))
- colWidths = tools.ustr(colWidths) + 'cm'
- for ans in que.answer_choice_ids:
- rml += """
-
-
- """
-
- elif que.type in ['table']:
- tbl_width = float(_tbl_widths.replace('cm',''))
- for i in range(0,len(que.column_heading_ids)):
- cols_widhts.append(tbl_width/float(len(que.column_heading_ids)))
- colWidths = "cm,".join(map(tools.ustr, cols_widhts))
- colWidths = colWidths+'cm'
- rml += """
"""
- for col in que.column_heading_ids:
- rml+="""
""" + to_xml(tools.ustr(col.title)) + """
"""
- rml += """
"""
- i = 0
- for r in range(0,que.no_of_rows):
- if i%2 != 0:
- style = 'tbl_white'
- else:
- style = 'tbl_gainsboro'
- i += 1
- rml += """
"""
- for c in que.column_heading_ids:
- rml += """
-
"""
- rml += """
"""
-
- if datas.has_key('form') and not datas['form']['without_pagebreak']:
- rml += """"""
- elif not datas.has_key('form'):
- rml += """"""
- else:
- rml += """"""
-
- rml += """"""
- report_type = datas.get('report_type', 'pdf')
- create_doc = self.generators[report_type]
- pdf = create_doc(rml, title=self.title)
- return (pdf, report_type)
-
-survey_form('report.survey.form', 'survey','','')
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/survey/security/ir.model.access.csv b/addons/survey/security/ir.model.access.csv
index b613e223afa..89c001ce44e 100644
--- a/addons/survey/security/ir.model.access.csv
+++ b/addons/survey/security/ir.model.access.csv
@@ -1,24 +1,22 @@
-id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_survey_type_manager,survey.type.manager,model_survey_type,base.group_tool_manager,1,1,1,1
-access_survey_request_manager,survey.request manager,model_survey_request,base.group_tool_manager,1,1,1,1
-access_survey_tbl_column_heading_manager,survey.tbl.column.heading manager,model_survey_tbl_column_heading,base.group_tool_manager,1,1,1,1
-access_survey_res_partner_user,survey.res.partner.user,base.model_res_partner,base.group_tool_user,1,1,1,1
-access_survey_user,survey.user,model_survey,base.group_tool_user,1,1,1,1
-access_survey_page_user,survey.page user,model_survey_page,base.group_tool_user,1,1,1,1
-access_survey_question_user,survey.question user,model_survey_question,base.group_tool_user,1,1,1,1
-access_survey_answer_user,survey.answer user,model_survey_answer,base.group_tool_user,1,1,1,1
-access_survey_response_user,survey.response user,model_survey_response,base.group_tool_user,1,1,1,1
-access_survey_response_answer_user,survey.response.answer user,model_survey_response_answer,base.group_tool_user,1,1,1,1
-access_survey_history_user,survey.history.user,model_survey_history,base.group_tool_user,1,1,1,1
-access_survey_response_line_user,survey.response.line user,model_survey_response_line,base.group_tool_user,1,1,1,1
-access_survey_res_partner_user,survey.res.partner.user,base.model_res_partner,base.group_tool_user,1,1,1,1
-access_survey_survey_user,survey.survey.user,model_survey,base.group_survey_user,1,1,1,1
-access_survey_page_survey_user,survey.page.survey.user,model_survey_page,base.group_survey_user,1,1,1,1
-access_survey_question_survey_user,survey.question.survey.user,model_survey_question,base.group_survey_user,1,1,1,1
-access_survey_answer_survey_user,survey.answer.survey.user,model_survey_answer,base.group_survey_user,1,1,1,1
-access_survey_response_survey_user,survey.response.survey.user,model_survey_response,base.group_survey_user,1,1,1,1
-access_survey_response_answer_survey_user,survey.response.answer.survey.user,model_survey_response_answer,base.group_survey_user,1,1,1,1
-access_survey_history_survey_user,survey.history.survey.user,model_survey_history,base.group_survey_user,1,1,1,1
-access_survey_response_line_survey_user,survey.response.line.survey.user,model_survey_response_line,base.group_survey_user,1,1,1,1
-access_survey_question_column_heading_survey_user,survey.question.column.heading.survey.user,model_survey_question_column_heading,base.group_survey_user,1,0,0,0
-access_survey_question_column_heading_user,survey.question.column.heading user,model_survey_question_column_heading,base.group_tool_user,1,1,1,1
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_survey_public,survey.survey public,model_survey_survey,base.group_public,1,0,0,0
+access_survey_page_public,survey.page public,model_survey_page,base.group_public,1,0,0,0
+access_survey_question_public,survey.question public,model_survey_question,base.group_public,1,0,0,0
+access_survey_label_public,survey.label public,model_survey_label,base.group_public,1,0,0,0
+access_survey_user_input_public,survey.user_input public,model_survey_user_input,base.group_public,1,1,1,0
+access_survey_user_input_line_public,survey.user_input_line public,model_survey_user_input_line,base.group_public,1,1,1,0
+access_survey_stage_public,survey.stage public,model_survey_stage,base.group_public,1,0,0,0
+access_survey_user,survey.survey user,model_survey_survey,base.group_survey_user,1,0,0,0
+access_survey_page_user,survey.page user,model_survey_page,base.group_survey_user,1,0,0,0
+access_survey_question_user,survey.question user,model_survey_question,base.group_survey_user,1,0,0,0
+access_survey_label_user,survey.label user,model_survey_label,base.group_survey_user,1,0,0,0
+access_survey_user_input_user,survey.user_input user,model_survey_user_input,base.group_survey_user,1,1,1,0
+access_survey_user_input_line_user,survey.user_input_line user,model_survey_user_input_line,base.group_survey_user,1,1,1,0
+access_survey_stage_user,survey.stage user,model_survey_stage,base.group_survey_user,1,0,0,0
+access_survey_manager,survey.survey manager,model_survey_survey,base.group_survey_manager,1,1,1,1
+access_survey_page_manager,survey.page manager,model_survey_page,base.group_survey_manager,1,1,1,1
+access_survey_question_manager,survey.question manager,model_survey_question,base.group_survey_manager,1,1,1,1
+access_survey_label_manager,survey.label manager,model_survey_label,base.group_survey_manager,1,1,1,1
+access_survey_user_input_manager,survey.user_input manager,model_survey_user_input,base.group_survey_manager,1,1,1,1
+access_survey_user_input_line_manager,survey.user_input_line manager,model_survey_user_input_line,base.group_survey_manager,1,1,1,1
+access_survey_stage_manager,survey.stage manager,model_survey_stage,base.group_survey_manager,1,1,1,1
\ No newline at end of file
diff --git a/addons/survey/security/survey_security.xml b/addons/survey/security/survey_security.xml
index 3b0cf5844ce..872e1049bcd 100644
--- a/addons/survey/security/survey_security.xml
+++ b/addons/survey/security/survey_security.xml
@@ -1,19 +1,84 @@
-
-
- User
-
-
-
- Manager
-
-
-
-
+
+
Survey / User
+
+
+
+
+ Survey / Manager
+
+
+
+
+ Public access to surveys
+
+ [('state', '=', 'open'), ('auth_required', '=', False)]
+
+
+
+
+
+
+
+
+ Access to survey for regular users
+
+ [('stage_id.closed', '=', False)]
+
+
+
+
+
+
+
+
+ Survey Manager access rights
+
+ [(1, '=', 1)]
+
+
+
+
+
+
+
+
+ Public access to user_input
+
+ [('create_uid', '=', user.id)]
+
+
+
+
+
+
+
+
+ Access to user_input for regular users
+
+ [('create_uid', '=', user.id)]
+
+
+
+
+
+
+
+
+ Survey Manager access rights
+
+ [(1, '=', 1)]
+
+
+
+
+
+
+
diff --git a/addons/survey/specification/specification.txt b/addons/survey/specification/specification.txt
deleted file mode 100644
index 673ca5bad17..00000000000
--- a/addons/survey/specification/specification.txt
+++ /dev/null
@@ -1,157 +0,0 @@
-Date : 8th October, 2009
-Created by : Harshad Modi(hmo) and Yogesh(ysa)
---------------------------------------------------------------------------------------
-
- **** Specification of Survay module in OpenERP ****
-
-
-Basic Requirements :
-======================================================================================
-> Design own survey form
-> Desing own Questionaries
-> Collect Response
-> Analyze Result
-
-Design own survey form:
----------------------------------------------------------------
-Allow to make multiple own survey pages with multiple questions with different question type.
-
-Note : After finish first Phase of Development, Allow to design page template to specify customize theme for bgcolor, bgimage, font style, font color
-
-
-Design Questinaries :
--------------------------------------------------------
-Questinaries should has :
-* can specify question text
-* can make Answer sheet
-Question Type:
-* Survey Admin can able to design answer option like:
-- Mutiple Choice with one answer
-- Mutilpe Choice with multiple answer
-
-
-Collect Response :
----------------------------------------------------------
-Survey Admin can able to :
-- Create a link
-- Send a survey invitation to others peple by mail
-- Allow to set max limit of Response
-- Survey Admin can able to close survey
-
-Analyze Result :
-----------------------------------------------------------
-- Show Result with all Survey pages with total responses, responce count and calculate avarage response.
-
-
-
-
-
-
-
-
-OpenERP model Design :
-====================================================================
-survey :
--------------------------------------------
-title - char(128)
-pages_ids - one2many(survey_page)
-date_open
-date_close
-survey_link
-max_response_limit
-status (draft, open, close, cancel)
-resposible - many2one (res.user)
-
-survey_page:
--------------------------------------------------------------------
-title - char(128)
-page_template_id - many2one( survey_page_template)
-survey_id - many2one(survey)
-question_ids - one2many(survey_question)
-sequence - int
-note - char(256)
-
-survey_question:
---------------------------------------------------------------
-page_id - many2one(survey_page)
-question - char(128)
-answer_choice_ids - one2many(survey_answer)
-response_ids - one2many(survey_response)
-is_require_answer
-allow_comment
-sequence - int
-
-survey_answer:
---------------------------------------------------------------------------
-question_id - many2one(survey_question)
-answer - char(128)
-sequence - int
-
-survey_response:
---------------------------------------------------------------------
-date_create
-date_modify
-status (done, skip)
-response_by - many2one(res.users)
-question_id - many2one(survey_question)
-response_type ( from manual, link, mail)
-response_answer_ids - one2many(survey_response_answer)
-
-survey_response_answer:
---------------------------------------------------------------------
-response_id - many2one(survey_response)
-question_id - many2one(survey_answer)
-comment
-
-
-OpenERP View Design:
-==================================================
-
-Survey View :
-
-see survey.png file
-
-Survey Pages View:
-
-see survey_page.png file
-
-Survey Question View:
-
-see survey_qyestion.png file
-
-Survey Response View :
-
-see survey_response.png file
-
-
-
-OpenERP Report Design :
-===================================================
-
-Design postgres view to display statistical information of response per question, response per user, etc..
-More detail will be provided later.
-
-
-OpenERP Menu Design :
-=====================================================
-
-Survey Management :
- > Surveys
- > All Surveys
- > New Survey
- > Survey Pages
- > All Survey Pages
- > New Survey Page
- > Survey Response
- > All Survey Responses
- > New Survey Response
- > Reports
- > Response per Survey
- > Response per Survey Page
- > Response per Question
- > Response per User
-
-References :
-===============================================
-http://www.surveymonkey.com/
-
diff --git a/addons/survey/specification/survey.png b/addons/survey/specification/survey.png
deleted file mode 100644
index 52acff391d0..00000000000
Binary files a/addons/survey/specification/survey.png and /dev/null differ
diff --git a/addons/survey/specification/survey_page.png b/addons/survey/specification/survey_page.png
deleted file mode 100644
index 4fceac4b81b..00000000000
Binary files a/addons/survey/specification/survey_page.png and /dev/null differ
diff --git a/addons/survey/specification/survey_question.png b/addons/survey/specification/survey_question.png
deleted file mode 100644
index 516606902cb..00000000000
Binary files a/addons/survey/specification/survey_question.png and /dev/null differ
diff --git a/addons/survey/specification/survey_response.png b/addons/survey/specification/survey_response.png
deleted file mode 100644
index af78bd1977d..00000000000
Binary files a/addons/survey/specification/survey_response.png and /dev/null differ
diff --git a/addons/survey/static/src/css/survey.css b/addons/survey/static/src/css/survey.css
deleted file mode 100644
index 15899533213..00000000000
--- a/addons/survey/static/src/css/survey.css
+++ /dev/null
@@ -1,13 +0,0 @@
-.openerp .oe_survey_title {
- font-weight: bold;
- font-size: 19px;
- margin: 8px 0px 8px 0px;
- color: #5B5B5B;
-}
-
-.openerp .oe_kanban_survey {
- /* Customize height and width according bootstrap3 */
- width: 212px;
- min-height: 86px !important;
- /* End of customize */
-}
diff --git a/addons/survey/static/src/css/survey_result.css b/addons/survey/static/src/css/survey_result.css
new file mode 100644
index 00000000000..9762bc3866f
--- /dev/null
+++ b/addons/survey/static/src/css/survey_result.css
@@ -0,0 +1,53 @@
+.only_right_radius {
+ border-top-right-radius: 2em;
+ border-bottom-right-radius: 2em;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+
+.only_left_radius {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-top-left-radius: 2em;
+ border-bottom-left-radius: 2em;
+}
+
+.no_radius {
+ border-radius: 0;
+}
+
+.clear_survey_filter, .filter-all, .filter-finished{
+ cursor: pointer;
+}
+
+.nvtooltip h5 {
+ margin: 0;
+ line-height: 18px;
+ font-weight: bold;
+ background-color: rgba(247,247,247,0.75);
+ text-align: center;
+ border-bottom: 1px solid #ebebeb;
+ -webkit-border-radius: 5px 5px 0 0;
+ -moz-border-radius: 5px 5px 0 0;
+ border-radius: 5px 5px 0 0;
+}
+
+
+.survey_answer i {
+ padding:3px;
+ cursor:pointer;
+}
+
+.survey_answer i.invisible {
+ visibility: hidden!important;
+}
+
+@media print {
+ .tab-content > .tab-pane {
+ display: block;
+ }
+
+ .tab-content > .survey_graph > svg {
+ width: 1150px;
+ }
+}
diff --git a/addons/survey/static/src/js/survey.js b/addons/survey/static/src/js/survey.js
new file mode 100644
index 00000000000..2d97250b0ce
--- /dev/null
+++ b/addons/survey/static/src/js/survey.js
@@ -0,0 +1,131 @@
+/*
+ * OpenERP, Open Source Management Solution
+ * Copyright (C) 2004-TODAY OpenERP S.A.
+ *
+ * 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 .
+ */
+
+/*
+ * This file is intended to add interactivity to survey forms rendered by
+ * the website engine.
+ */
+
+$(document).ready(function () {
+ 'use strict';
+
+ console.debug("[survey] Custom JS for survey is loading...");
+
+ var the_form = $('.js_surveyform');
+ var prefill_controller = the_form.attr("data-prefill");
+ var validate_controller = the_form.attr("data-validate");
+ var submit_controller = the_form.attr("data-submit");
+ var print_mode = false;
+
+ // Printing mode: will disable all the controls in the form
+ if (_.isUndefined(submit_controller)) {
+ $('.js_surveyform :input').prop('disabled', true);
+ print_mode = true;
+ }
+
+ // Custom code for right behavior of radio buttons with comments box
+ $('.js_comments>input[type="text"]').focusin(function(){
+ $(this).prev().find('>input').attr("checked","checked");
+ });
+ $('.js_radio input[type="radio"][data-oe-survey-otherr!="1"]').click(function(){
+ $(this).closest('.js_radio').find('.js_comments>input[type="text"]').val("");
+ });
+ $('.js_comments input[type="radio"]').click(function(){
+ $(this).closest('.js_comments').find('>input[data-oe-survey-othert="1"]').focus();
+ });
+ // Custom code for right behavior of dropdown menu with comments
+ $('.js_drop input[data-oe-survey-othert="1"]').hide();
+ $('.js_drop select').change(function(){
+ var other_val = $(this).find('.js_other_option').val();
+ if($(this).val() === other_val){
+ $(this).parent().removeClass('col-md-12').addClass('col-md-6');
+ $(this).closest('.js_drop').find('input[data-oe-survey-othert="1"]').show().focus();
+ }
+ else{
+ $(this).parent().removeClass('col-md-6').addClass('col-md-12');
+ $(this).closest('.js_drop').find('input[data-oe-survey-othert="1"]').val("").hide();
+ }
+ });
+ // Custom code for right behavior of checkboxes with comments box
+ $('.js_ck_comments>input[type="text"]').focusin(function(){
+ $(this).prev().find('>input').attr("checked","checked");
+ });
+ $('.js_ck_comments input[type="checkbox"]').change(function(){
+ if (! $(this).prop("checked")){
+ $(this).closest('.js_ck_comments').find('input[type="text"]').val("");
+ }
+ });
+
+ // Pre-filling of the form with previous answers
+ function prefill(){
+ var prefill_def = $.ajax(prefill_controller, {dataType: "json"})
+ .done(function(json_data){
+ _.each(json_data, function(value, key){
+ the_form.find(".form-control[name=" + key + "]").val(value);
+ the_form.find("input[name^=" + key + "]").each(function(){
+ $(this).val(value);
+ });
+ });
+ })
+ .fail(function(){
+ console.warn("[survey] Unable to load prefill data");
+ });
+ return prefill_def;
+ }
+
+ // Parameters for form submission
+ $('.js_surveyform').ajaxForm({
+ url: submit_controller,
+ type: 'POST', // submission type
+ dataType: 'json', // answer expected type
+ beforeSubmit: function(){ // hide previous errmsg before resubmitting
+ $('.js_errzone').html("").hide();
+ },
+ success: function(response, status, xhr, wfe){ // submission attempt
+ if(_.has(response, 'errors')){ // some questions have errors
+ _.each(_.keys(response.errors), function(key){
+ $("#" + key + '>.js_errzone').append('
' + response.errors[key] + '
').show();
+ });
+ return false;
+ }
+ else if (_.has(response, 'redirect')){ // form is ok
+ window.location.replace(response.redirect);
+ return true;
+ }
+ else { // server sends bad data
+ console.error("Incorrect answer sent by server");
+ return false;
+ }
+ },
+ timeout: 5000,
+ error: function(jqXHR, textStatus, errorThrown){ // failure of AJAX request
+ $('#AJAXErrorModal').modal('show');
+ }
+ });
+
+ // // Handles the event when a question is focused out
+ // $('.js_question-wrapper').focusout(
+ // function(){
+ // console.debug("[survey] Focus lost on question " + $(this).attr("id"));
+ // });
+
+ // Launch prefilling
+ prefill();
+
+ console.debug("[survey] Custom JS for survey loaded!");
+});
diff --git a/addons/survey/static/src/js/survey_result.js b/addons/survey/static/src/js/survey_result.js
new file mode 100644
index 00000000000..7c9b935582a
--- /dev/null
+++ b/addons/survey/static/src/js/survey_result.js
@@ -0,0 +1,177 @@
+/*
+ * OpenERP, Open Source Management Solution
+ * Copyright (C) 2004-TODAY OpenERP S.A.
+ *
+ * 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 .
+ */
+
+$(document).ready(function () {
+ 'use strict';
+ console.debug("[survey] Survey Result JS is loading...");
+
+ //Script For Pagination
+ var survey_pagination = $('.pagination');
+ $.each(survey_pagination, function(index, pagination){
+ var question_id = $(pagination).attr("data-question_id");
+ var limit = $(pagination).attr("data-record_limit"); //Number of Record Par Page. If you want to change number of record per page, change record_limit in pagination template.
+ $('#table_question_'+ question_id +' tbody tr:lt('+limit+')').removeClass('hidden');
+ $('#pagination_'+question_id+' li:first').addClass('active');
+ $('#pagination_'+question_id+' li a').click(function(event){
+ event.preventDefault();
+ $('#pagination_'+question_id+' li').removeClass('active');
+ $(this).parent('li').addClass('active');
+ $('#table_question_'+ question_id +' tbody tr').addClass('hidden');
+ var num = $(this).text();
+ var min = (limit * (num-1))-1;
+ if (min == -1){
+ $('#table_question_'+ question_id +' tbody tr:lt('+ limit * num +')').removeClass('hidden');
+ }
+ else{
+ $('#table_question_'+question_id+' tbody tr:lt('+ limit * num +'):gt('+min+')').removeClass('hidden');
+ }
+ });
+ });
+
+ //initialize MultiBar Chart
+ function init_multibar_chart(){
+ var chart = nv.models.multiBarChart()
+ .x(function(d) { return d.text; })
+ .y(function(d) { return d.count; })
+ .staggerLabels(true);
+
+ // Replacing Library's Default Tooltip with our Custom One
+ chart.tooltip(function(key, x, y, e, graph) {
+ return '
' + x + '
' +
+ '
' + 'Responses : ' + key + '
' +
+ '
' + "Total Vote : " + y + '
';
+ });
+ return chart;
+ }
+
+ //initialize discreteBar Chart
+ function init_bar_chart(){
+ return nv.models.discreteBarChart()
+ .x(function(d) { return d.text; })
+ .y(function(d) { return d.count; })
+ .staggerLabels(true)
+ .tooltips(false)
+ .showValues(true);
+ }
+
+ //initialize Pie Chart
+ function init_pie_chart(){
+ return nv.models.pieChart()
+ .x(function(d) { return d.text; })
+ .y(function(d) { return d.count; })
+ .showLabels(false);
+ }
+
+ //load chart to svg element chart:initialized chart, response:AJAX response, quistion_id:if of survey question, tick_limit:text length limit
+ function load_chart(chart, response, question_id, tick_limit, graph_type){
+ // Custom Tick fuction for replacing long text with '...'
+ var customtick_function = function(d){
+ if(! this || d.length <= tick_limit){
+ return d;
+ }
+ else{
+ return d.slice(0,tick_limit) + '...';
+ }
+ };
+ if (graph_type != 'pie'){
+ chart.xAxis
+ .tickFormat(customtick_function);
+ chart.yAxis
+ .tickFormat(d3.format('d'));
+ }
+ d3.select('#graph_question_' + question_id + ' svg')
+ .datum(response)
+ .transition().duration(500).call(chart);
+ nv.utils.windowResize(chart.update);
+ return chart;
+ }
+ //Script For Graph
+ var survey_graphs = $('.survey_graph');
+ $.each(survey_graphs, function(index, graph){
+ var question_id = $(graph).attr("data-question_id");
+ var graph_type = $(graph).attr("data-graph_type");
+ var graph_data = JSON.parse($(graph).attr("graph-data"));
+ if(graph_type == 'multi_bar'){
+ nv.addGraph(function(){
+ var chart = init_multibar_chart();
+ return load_chart(chart, graph_data, question_id, 25);
+ });
+ }
+ else if(graph_type == 'bar'){
+ nv.addGraph(function() {
+ var chart = init_bar_chart();
+ return load_chart(chart, graph_data, question_id, 35);
+ });
+ }
+ else if(graph_type == 'pie'){
+ nv.addGraph(function() {
+ var chart = init_pie_chart();
+ return load_chart(chart, graph_data, question_id, 25, 'pie');
+ });
+ }
+ });
+
+ // Script for filter
+ $('td.survey_answer').hover(function(){
+ $(this).find('i.fa-filter').removeClass('invisible');
+ }, function(){
+ $(this).find('i.fa-filter').addClass('invisible');
+ });
+ $('td.survey_answer i.fa-filter').click(function(){
+ var cell = $(this);
+ var row_id = cell.attr('data-row_id') | 0;
+ var answer_id = cell.attr('data-answer_id');
+ if(document.URL.indexOf("?") == -1){
+ window.location.href = document.URL + '?' + encodeURI(row_id + ',' + answer_id);
+ }
+ else {
+ window.location.href = document.URL + '&' + encodeURI(row_id + ',' + answer_id);
+ }
+ });
+
+ // for clear all filters
+ $('.clear_survey_filter').click(function(){
+ window.location.href = document.URL.substring(0,document.URL.indexOf("?"));
+ });
+ $('span.filter-all').click(function(){
+ event.preventDefault();
+ if(document.URL.indexOf("finished") != -1){
+ window.location.href = document.URL.replace('?finished&','?').replace('&finished&','&').replace('?finished','').replace('&finished','');
+ }
+ }).hover(function(){
+ if(document.URL.indexOf("finished") == -1){
+ $(this)[0].style.cursor = 'default';
+ }
+ });
+ // toggle finished/all surveys filter
+ $('span.filter-finished').click(function(){
+ event.preventDefault();
+ if(document.URL.indexOf("?") == -1){
+ window.location.href = document.URL + '?' + encodeURI('finished');
+ }
+ else if(document.URL.indexOf("finished") == -1){
+ window.location.href = document.URL + '&' + encodeURI('finished');
+ }
+ }).hover(function(){
+ if(document.URL.indexOf("finished") != -1){
+ $(this)[0].style.cursor = 'default';
+ }
+ });
+
+ console.debug("[survey] Survey Result JS loaded!");
+});
\ No newline at end of file
diff --git a/addons/survey/survey.py b/addons/survey/survey.py
index 37a0c6ed773..eaf7a898df5 100644
--- a/addons/survey/survey.py
+++ b/addons/survey/survey.py
@@ -4,7 +4,7 @@
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-TODAY OpenERP S.A.
#
-# This program is free software: you can redistribute it and/or modify
+# 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.
@@ -19,760 +19,1204 @@
#
##############################################################################
-import copy
-from datetime import datetime
-from dateutil.relativedelta import relativedelta
-from time import strftime
-import os
-
-from openerp import tools
from openerp.osv import fields, osv
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
-class survey_type(osv.osv):
- _name = 'survey.type'
- _description = 'Survey Type'
- _columns = {
- 'name': fields.char("Name", size=128, required=1, translate=True),
- 'code': fields.char("Code", size=64),
- }
+import datetime
+import logging
+import re
+import uuid
-class survey(osv.osv):
- _name = 'survey'
+_logger = logging.getLogger(__name__)
+
+
+class survey_survey(osv.Model):
+ '''Settings for a multi-page/multi-question survey.
+ Each survey can have one or more attached pages, and each page can display
+ one or more questions.
+ '''
+
+ _name = 'survey.survey'
_description = 'Survey'
_rec_name = 'title'
+ _inherit = ['mail.thread', 'ir.needaction_mixin']
- def default_get(self, cr, uid, fields, context=None):
- data = super(survey, self).default_get(cr, uid, fields, context)
- return data
+ # Protected methods #
+
+ def _has_questions(self, cr, uid, ids, context=None):
+ """ Ensure that this survey has at least one page with at least one
+ question. """
+ for survey in self.browse(cr, uid, ids, context=context):
+ if not survey.page_ids or not [page.question_ids
+ for page in survey.page_ids if page.question_ids]:
+ return False
+ return True
+
+ ## Function fields ##
+
+ def _is_designed(self, cr, uid, ids, name, arg, context=None):
+ res = dict()
+ for survey in self.browse(cr, uid, ids, context=context):
+ if not survey.page_ids or not [page.question_ids
+ for page in survey.page_ids if page.question_ids]:
+ res[survey.id] = False
+ else:
+ res[survey.id] = True
+ return res
+
+ def _get_tot_sent_survey(self, cr, uid, ids, name, arg, context=None):
+ """ Returns the number of invitations sent for this survey, be they
+ (partially) completed or not """
+ res = dict((id, 0) for id in ids)
+ sur_res_obj = self.pool.get('survey.user_input')
+ for id in ids:
+ res[id] = sur_res_obj.search(cr, uid, # SUPERUSER_ID,
+ [('survey_id', '=', id), ('type', '=', 'link')],
+ context=context, count=True)
+ return res
+
+ def _get_tot_start_survey(self, cr, uid, ids, name, arg, context=None):
+ """ Returns the number of started instances of this survey, be they
+ completed or not """
+ res = dict((id, 0) for id in ids)
+ sur_res_obj = self.pool.get('survey.user_input')
+ for id in ids:
+ res[id] = sur_res_obj.search(cr, uid, # SUPERUSER_ID,
+ ['&', ('survey_id', '=', id), '|', ('state', '=', 'skip'), ('state', '=', 'done')],
+ context=context, count=True)
+ return res
+
+ def _get_tot_comp_survey(self, cr, uid, ids, name, arg, context=None):
+ """ Returns the number of completed instances of this survey """
+ res = dict((id, 0) for id in ids)
+ sur_res_obj = self.pool.get('survey.user_input')
+ for id in ids:
+ res[id] = sur_res_obj.search(cr, uid, # SUPERUSER_ID,
+ [('survey_id', '=', id), ('state', '=', 'done')],
+ context=context, count=True)
+ return res
+
+ def _get_public_url(self, cr, uid, ids, name, arg, context=None):
+ """ Computes a public URL for the survey """
+ base_url = self.pool.get('ir.config_parameter').get_param(cr, uid,
+ 'web.base.url')
+ res = {}
+ for survey in self.browse(cr, uid, ids, context=context):
+ res[survey.id] = urljoin(base_url, "survey/start/%s" % slug(survey))
+ return res
+
+ def _get_public_url_html(self, cr, uid, ids, name, arg, context=None):
+ """ Computes a public URL for the survey (html-embeddable version)"""
+ urls = self._get_public_url(cr, uid, ids, name, arg, context=context)
+ for id, url in urls.iteritems():
+ urls[id] = '%s' % (url, _("Click here to start survey"))
+ return urls
+
+ def _get_print_url(self, cr, uid, ids, name, arg, context=None):
+ """ Computes a printing URL for the survey """
+ base_url = self.pool.get('ir.config_parameter').get_param(cr, uid,
+ 'web.base.url')
+ res = {}
+ for survey in self.browse(cr, uid, ids, context=context):
+ res[survey.id] = urljoin(base_url, "survey/print/%s" % slug(survey))
+ return res
+
+ def _get_result_url(self, cr, uid, ids, name, arg, context=None):
+ """ Computes an URL for the survey results """
+ base_url = self.pool.get('ir.config_parameter').get_param(cr, uid,
+ 'web.base.url')
+ res = {}
+ for survey in self.browse(cr, uid, ids, context=context):
+ res[survey.id] = urljoin(base_url, "survey/results/%s" % slug(survey))
+ return res
+
+ # Model fields #
_columns = {
- 'id': fields.integer('ID'),
- 'title': fields.char('Survey Title', size=128, required=1),
- 'page_ids': fields.one2many('survey.page', 'survey_id', 'Page'),
- 'date_open': fields.datetime('Survey Open Date', readonly=1),
- 'date_close': fields.datetime('Survey Close Date', readonly=1),
- 'max_response_limit': fields.integer('Maximum Answer Limit',
- help="Set to one if survey is answerable only once"),
- 'response_user': fields.integer('Maximum Answer per User',
- help="Set to one if you require only one Answer per user"),
- 'state': fields.selection([('open', 'Open'), ('cancel', 'Cancelled'),('close', 'Closed') ], 'Status', readonly=True),
- 'responsible_id': fields.many2one('res.users', 'Responsible', help="User responsible for survey"),
- 'tot_start_survey': fields.integer("Total Started Survey", readonly=1),
- 'tot_comp_survey': fields.integer("Total Completed Survey", readonly=1),
- 'note': fields.text('Description', size=128),
- 'history': fields.one2many('survey.history', 'survey_id', 'History Lines', readonly=True),
- 'users': fields.many2many('res.users', 'survey_users_rel', 'sid', 'uid', 'Users'),
- 'send_response': fields.boolean('Email Notification on Answer'),
- 'type': fields.many2one('survey.type', 'Type'),
+ 'title': fields.char('Title', required=1, translate=True),
+ 'res_model': fields.char('Category'),
+ 'page_ids': fields.one2many('survey.page', 'survey_id', 'Pages'),
+ 'stage_id': fields.many2one('survey.stage', string="Stage", ondelete="set null"),
+ 'auth_required': fields.boolean('Login required',
+ help="Users with a public link will be requested to login before taking part to the survey",
+ oldname="authenticate"),
+ 'users_can_go_back': fields.boolean('Users can go back',
+ help="If checked, users can go back to previous pages."),
+ 'tot_sent_survey': fields.function(_get_tot_sent_survey,
+ string="Number of sent surveys", type="integer"),
+ 'tot_start_survey': fields.function(_get_tot_start_survey,
+ string="Number of started surveys", type="integer"),
+ 'tot_comp_survey': fields.function(_get_tot_comp_survey,
+ string="Number of completed surveys", type="integer"),
+ 'description': fields.html('Description', translate=True,
+ oldname="description", help="A long description of the purpose of the survey"),
'color': fields.integer('Color Index'),
- 'invited_user_ids': fields.many2many('res.users', 'survey_invited_user_rel', 'sid', 'uid', 'Invited User'),
+ 'user_input_ids': fields.one2many('survey.user_input', 'survey_id',
+ 'User responses', readonly=1),
+ 'designed': fields.function(_is_designed, string="Is designed?",
+ type="boolean"),
+ 'public_url': fields.function(_get_public_url,
+ string="Public link", type="char"),
+ 'public_url_html': fields.function(_get_public_url_html,
+ string="Public link (html version)", type="char"),
+ 'print_url': fields.function(_get_print_url,
+ string="Print link", type="char"),
+ 'result_url': fields.function(_get_result_url,
+ string="Results link", type="char"),
+ 'email_template_id': fields.many2one('email.template',
+ 'Email Template', ondelete='set null'),
+ 'thank_you_message': fields.html('Thank you message', translate=True,
+ help="This message will be displayed when survey is completed"),
+ 'quizz_mode': fields.boolean(string='Quizz mode')
}
+
_defaults = {
- 'state': lambda * a: "open",
- 'tot_start_survey': lambda * a: 0,
- 'tot_comp_survey': lambda * a: 0,
- 'send_response': lambda * a: 1,
- 'response_user': lambda * a:1,
- 'date_open': fields.datetime.now,
+ 'color': 0,
+ 'stage_id': lambda self, cr, uid, context: self.pool.get('survey.stage').search_read(cr, uid, fields=['id'], order='sequence asc', limit=1, context=context)[0]['id']
}
- def survey_open(self, cr, uid, ids, arg):
- self.write(cr, uid, ids, {'state': 'open', 'date_open': strftime("%Y-%m-%d %H:%M:%S")})
- return True
+ def _read_group_stage_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None):
+ """ Read group customization in order to display all the stages in the
+ kanban view, even if they are empty """
+ stage_obj = self.pool.get('survey.stage')
+ order = stage_obj._order
+ access_rights_uid = access_rights_uid or uid
- def survey_close(self, cr, uid, ids, arg):
- self.write(cr, uid, ids, {'state': 'close', 'date_close': strftime("%Y-%m-%d %H:%M:%S") })
- return True
+ if read_group_order == 'stage_id desc':
+ order = '%s desc' % order
- def survey_cancel(self, cr, uid, ids, arg):
- self.write(cr, uid, ids, {'state': 'cancel' })
- return True
+ stage_ids = stage_obj._search(cr, uid, [], order=order, access_rights_uid=access_rights_uid, context=context)
+ result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context)
- def copy(self, cr, uid, ids, default=None, context=None):
- vals = {}
- current_rec = self.read(cr, uid, ids, context=context)
+ # restore order of the search
+ result.sort(lambda x, y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0])))
+
+ fold = {}
+ for stage in stage_obj.browse(cr, access_rights_uid, stage_ids, context=context):
+ fold[stage.id] = stage.fold or False
+ return result, fold
+
+ _group_by_full = {
+ 'stage_id': _read_group_stage_ids
+ }
+
+ # Public methods #
+
+ def copy_data(self, cr, uid, id, default=None, context=None):
+ vals = dict()
+ current_rec = self.read(cr, uid, id, fields=['title'], context=context)
title = _("%s (copy)") % (current_rec.get('title'))
- vals.update({'title':title})
- vals.update({'history':[],'tot_start_survey':0,'tot_comp_survey':0})
- return super(survey, self).copy(cr, uid, ids, vals, context=context)
+ vals['title'] = title
+ vals['user_input_ids'] = []
+ return super(survey_survey, self).copy_data(cr, uid, id, default=vals,
+ context=context)
+
+ def next_page(self, cr, uid, user_input, page_id, go_back=False, context=None):
+ '''The next page to display to the user, knowing that page_id is the id
+ of the last displayed page.
+
+ If page_id == 0, it will always return the first page of the survey.
+
+ If all the pages have been displayed and go_back == False, it will
+ return None
+
+ If go_back == True, it will return the *previous* page instead of the
+ next page.
+
+ .. note::
+ It is assumed here that a careful user will not try to set go_back
+ to True if she knows that the page to display is the first one!
+ (doing this will probably cause a giant worm to eat her house)'''
+ survey = user_input.survey_id
+ pages = list(enumerate(survey.page_ids))
+
+ # First page
+ if page_id == 0:
+ return (pages[0][1], 0, len(pages) == 1)
+
+ current_page_index = pages.index((filter(lambda p: p[1].id == page_id, pages))[0])
+
+ # All the pages have been displayed
+ if current_page_index == len(pages) - 1 and not go_back:
+ return (None, -1, False)
+ # Let's get back, baby!
+ elif go_back and survey.users_can_go_back:
+ return (pages[current_page_index - 1][1], current_page_index - 1, False)
+ else:
+ # This will show the last page
+ if current_page_index == len(pages) - 2:
+ return (pages[current_page_index + 1][1], current_page_index + 1, True)
+ # This will show a regular page
+ else:
+ return (pages[current_page_index + 1][1], current_page_index + 1, False)
+
+ def filter_input_ids(self, cr, uid, filters, finished=False, context=None):
+ '''If user applies any filters, then this function returns list of
+ filtered user_input_id and label's strings for display data in web.
+ :param filters: list of dictionary (having: row_id, ansewr_id)
+ :param finished: True for completely filled survey,Falser otherwise.
+ :returns list of filtered user_input_ids.
+ '''
+ if context is None:
+ context = {}
+ if filters:
+ input_line_obj = self.pool.get('survey.user_input_line')
+ domain_filter, choice, filter_display_data = [], [], []
+ for filter in filters:
+ row_id, answer_id = filter['row_id'], filter['answer_id']
+ if row_id == 0:
+ choice.append(answer_id)
+ else:
+ domain_filter.extend(['|', ('value_suggested_row.id', '=', row_id), ('value_suggested.id', '=', answer_id)])
+ if choice:
+ domain_filter.insert(0, ('value_suggested.id', 'in', choice))
+ else:
+ domain_filter = domain_filter[1:]
+ line_ids = input_line_obj.search(cr, uid, domain_filter, context=context)
+ filtered_input_ids = [input.user_input_id.id for input in input_line_obj.browse(cr, uid, line_ids, context=context)]
+ else:
+ filtered_input_ids, filter_display_data = [], []
+ if finished:
+ user_input = self.pool.get('survey.user_input')
+ if not filtered_input_ids:
+ current_filters = user_input.search(cr, uid, [], context=context)
+ user_input_objs = user_input.browse(cr, uid, current_filters, context=context)
+ else:
+ user_input_objs = user_input.browse(cr, uid, filtered_input_ids, context=context)
+ return [input.id for input in user_input_objs if input.state == 'done']
+ return filtered_input_ids
+
+ def get_filter_display_data(self, cr, uid, filters, context):
+ '''Returns data to display current filters
+ :param filters: list of dictionary (having: row_id, answer_id)
+ :param finished: True for completely filled survey, False otherwise.
+ :returns list of dict having data to display filters.
+ '''
+ filter_display_data = []
+ if filters:
+ question_obj = self.pool.get('survey.question')
+ label_obj = self.pool.get('survey.label')
+ for filter in filters:
+ row_id, answer_id = filter['row_id'], filter['answer_id']
+ question_id = label_obj.browse(cr, uid, answer_id, context=context).question_id.id
+ question = question_obj.browse(cr, uid, question_id, context=context)
+ if row_id == 0:
+ labels = label_obj.browse(cr, uid, [answer_id], context=context)
+ else:
+ 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):
+ ''' Compute statistical data for questions by counting number of vote per choice on basis of filter '''
+ 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 input_line.answer_type == 'suggestion' and 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 input_line.answer_type == 'suggestion' and 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 '''
+ 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
+
+ # Actions
+
+ def action_start_survey(self, cr, uid, ids, context=None):
+ ''' Open the website page with the survey form '''
+ trail = ""
+ if context and 'survey_token' in context:
+ trail = "/" + context['survey_token']
+ return {
+ 'type': 'ir.actions.act_url',
+ 'name': "Start Survey",
+ 'target': 'self',
+ 'url': self.read(cr, uid, ids, ['public_url'], context=context)[0]['public_url'] + trail
+ }
+
+ def action_send_survey(self, cr, uid, ids, context=None):
+ ''' Open a window to compose an email, pre-filled with the survey
+ message '''
+ if not self._has_questions(cr, uid, ids, context=None):
+ raise osv.except_osv(_('Error!'), _('You cannot send an invitation for a survey that has no questions.'))
+
+ survey_browse = self.pool.get('survey.survey').browse(cr, uid, ids,
+ context=context)[0]
+ if survey_browse.stage_id.closed:
+ raise osv.except_osv(_('Warning!'),
+ _("You cannot send invitations for closed surveys."))
+
+ assert len(ids) == 1, 'This option should only be used for a single \
+ survey at a time.'
+ ir_model_data = self.pool.get('ir.model.data')
+ templates = ir_model_data.get_object_reference(cr, uid,
+ 'survey', 'email_template_survey')
+ template_id = templates[1] if len(templates) > 0 else False
+ ctx = dict(context)
+
+ ctx.update({'default_model': 'survey.survey',
+ 'default_res_id': ids[0],
+ 'default_survey_id': ids[0],
+ 'default_use_template': bool(template_id),
+ 'default_template_id': template_id,
+ 'default_composition_mode': 'comment'}
+ )
+ return {
+ 'type': 'ir.actions.act_window',
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': 'survey.mail.compose.message',
+ 'target': 'new',
+ 'context': ctx,
+ }
def action_print_survey(self, cr, uid, ids, context=None):
- """
- If response is available then print this response otherwise print survey form(print template of the survey).
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of Survey IDs
- @param context: A standard dictionary for contextual values
- @return : Dictionary value for print survey form.
- """
- if context is None:
- context = {}
- datas = {}
- if 'response_id' in context:
- response_id = context.get('response_id', 0)
- datas['ids'] = [context.get('survey_id', 0)]
- else:
- response_id = self.pool.get('survey.response').search(cr, uid, [('survey_id','=', ids)], context=context)
- datas['ids'] = ids
- page_setting = {'orientation': 'vertical', 'without_pagebreak': 0, 'paper_size': 'letter', 'page_number': 1, 'survey_title': 1}
- report = {}
- if response_id and response_id[0]:
- context.update({'survey_id': datas['ids']})
- datas['form'] = page_setting
- datas['model'] = 'survey.print.answer'
- report = {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'survey.browse.response',
- 'datas': datas,
- 'context' : context,
- 'nodestroy':True,
- }
- else:
-
- datas['form'] = page_setting
- datas['model'] = 'survey.print'
- report = {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'survey.form',
- 'datas': datas,
- 'context' : context,
- 'nodestroy':True,
- }
- return report
-
- def fill_survey(self, cr, uid, ids, context=None):
- sur_obj = self.read(cr, uid, ids,['title', 'page_ids'], context=context)
- for sur in sur_obj:
- name = sur['title']
- pages = sur['page_ids']
- if not pages:
- raise osv.except_osv(_('Warning!'), _('This survey has no question defined. Please define the questions and answers first.'))
- context.update({'active':False,'survey_id': ids[0]})
+ ''' Open the website page with the survey printable view '''
+ trail = ""
+ if context and 'survey_token' in context:
+ trail = "/" + context['survey_token']
return {
- 'view_type': 'form',
- 'view_mode': 'form',
- 'res_model': 'survey.question.wiz',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'name': name,
- 'context': context
- }
- def test_survey(self, cr, uid, ids, context=None):
- sur_obj = self.read(cr, uid, ids,['title','page_ids'], context=context)
- for sur in sur_obj:
- name = sur['title']
- pages = sur['page_ids']
- if not pages:
- raise osv.except_osv(_('Warning!'), _('This survey has no pages defined. Please define pages first.'))
- context.update({'active':False,'survey_id': ids[0]})
- return {
- 'view_type': 'form',
- 'view_mode': 'form',
- 'res_model': 'survey.question.wiz',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'name': name,
- 'context': context
+ 'type': 'ir.actions.act_url',
+ 'name': "Print Survey",
+ 'target': 'self',
+ 'url': self.read(cr, uid, ids, ['print_url'], context=context)[0]['print_url'] + trail
}
- def edit_survey(self, cr, uid, ids, context=None):
- sur_obj = self.read(cr, uid, ids,['title','page_ids'], context=context)
- for sur in sur_obj:
- name = sur['title']
- pages = sur['page_ids']
- if not pages:
- raise osv.except_osv(_('Warning!'), _('This survey has no question defined. Please define the questions and answers first.'))
- context.update({'survey_id': ids[0]})
+ def action_result_survey(self, cr, uid, ids, context=None):
+ ''' Open the website page with the survey results view '''
return {
- 'view_type': 'form',
- 'view_mode': 'form',
- 'res_model': 'survey.question.wiz',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'name': name,
- 'context': context
+ 'type': 'ir.actions.act_url',
+ 'name': "Results of the Survey",
+ 'target': 'self',
+ 'url': self.read(cr, uid, ids, ['result_url'], context=context)[0]['result_url']
+ }
+
+ def action_test_survey(self, cr, uid, ids, context=None):
+ ''' Open the website page with the survey form into test mode'''
+ return {
+ 'type': 'ir.actions.act_url',
+ 'name': "Results of the Survey",
+ 'target': 'self',
+ 'url': self.read(cr, uid, ids, ['public_url'], context=context)[0]['public_url'] + "/phantom"
}
-class survey_history(osv.osv):
- _name = 'survey.history'
- _description = 'Survey History'
- _rec_name = 'date'
+class survey_stage(osv.Model):
+ """Stages for Kanban view of surveys"""
+
+ _name = 'survey.stage'
+ _description = 'Survey Stage'
+ _order = 'sequence asc'
+
_columns = {
- 'survey_id': fields.many2one('survey', 'Survey'),
- 'user_id': fields.many2one('res.users', 'User', readonly=True),
- 'date': fields.datetime('Date started', readonly=1),
+ 'name': fields.char(string="Name", required=True, translate=True),
+ 'sequence': fields.integer(string="Sequence"),
+ 'closed': fields.boolean(string="Closed", help="If closed, people won't be able to answer to surveys in this column."),
+ 'fold': fields.boolean(string="Folded in kanban view")
}
_defaults = {
- 'date': lambda * a: datetime.datetime.now()
+ 'sequence': 1,
+ 'closed': False
}
+ _sql_constraints = [
+ ('positive_sequence', 'CHECK(sequence >= 0)', 'Sequence number MUST be a natural')
+ ]
+
+
+class survey_page(osv.Model):
+ '''A page for a survey.
+
+ Pages are essentially containers, allowing to group questions by ordered
+ screens.
+
+ .. note::
+ A page should be deleted if the survey it belongs to is deleted. '''
-class survey_page(osv.osv):
_name = 'survey.page'
- _description = 'Survey Pages'
+ _description = 'Survey Page'
_rec_name = 'title'
_order = 'sequence'
+
+ # Model Fields #
+
_columns = {
- 'title': fields.char('Page Title', size=128, required=1),
- 'survey_id': fields.many2one('survey', 'Survey', ondelete='cascade'),
- 'question_ids': fields.one2many('survey.question', 'page_id', 'Questions'),
- 'sequence': fields.integer('Page Nr'),
- 'note': fields.text('Description'),
+ 'title': fields.char('Page Title', required=1,
+ translate=True),
+ 'survey_id': fields.many2one('survey.survey', 'Survey',
+ ondelete='cascade', required=True),
+ 'question_ids': fields.one2many('survey.question', 'page_id',
+ 'Questions'),
+ 'sequence': fields.integer('Page number'),
+ 'description': fields.html('Description',
+ help="An introductory text to your page", translate=True,
+ oldname="note"),
}
_defaults = {
- 'sequence': lambda * a: 1
+ 'sequence': 10
}
- def default_get(self, cr, uid, fields, context=None):
- if context is None:
- context = {}
- data = super(survey_page, self).default_get(cr, uid, fields, context)
- if context.has_key('survey_id'):
- data['survey_id'] = context.get('survey_id', False)
- return data
+ # Public methods #
- def survey_save(self, cr, uid, ids, context=None):
- if context is None:
- context = {}
- search_obj = self.pool.get('ir.ui.view')
- search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
- surv_name_wiz = self.pool.get('survey.name.wiz')
- surv_name_wiz.write(cr, uid, [context.get('sur_name_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',
- 'search_view_id': search_id[0],
- 'context': context
- }
-
- def copy(self, cr, uid, ids, default=None, context=None):
+ def copy_data(self, cr, uid, ids, default=None, context=None):
vals = {}
- current_rec = self.read(cr, uid, ids, context=context)
+ current_rec = self.read(cr, uid, ids, fields=['title'], context=context)
title = _("%s (copy)") % (current_rec.get('title'))
- vals.update({'title':title})
- return super(survey_page, self).copy(cr, uid, ids, vals, context=context)
+ vals.update({'title': title})
+ return super(survey_page, self).copy_data(cr, uid, ids, default=vals,
+ context=context)
-class survey_question(osv.osv):
+class survey_question(osv.Model):
+ ''' Questions that will be asked in a survey.
+
+ Each question can have one of more suggested answers (eg. in case of
+ dropdown choices, multi-answer checkboxes, radio buttons...).'''
_name = 'survey.question'
_description = 'Survey Question'
_rec_name = 'question'
_order = 'sequence'
- def _calc_response(self, cr, uid, ids, field_name, arg, context=None):
- if len(ids) == 0:
- return {}
- val = {}
- cr.execute("select question_id, count(id) as Total_response from \
- survey_response_line where state='done' and question_id IN %s\
- group by question_id" ,(tuple(ids),))
- ids1 = copy.deepcopy(ids)
- for rec in cr.fetchall():
- ids1.remove(rec[0])
- val[rec[0]] = int(rec[1])
- for id in ids1:
- val[id] = 0
- return val
+ # Model fields #
_columns = {
- 'page_id': fields.many2one('survey.page', 'Survey Page', ondelete='cascade', required=1),
- 'question': fields.char('Question', size=128, required=1),
- 'answer_choice_ids': fields.one2many('survey.answer', 'question_id', 'Answer'),
- 'is_require_answer': fields.boolean('Require Answer to Question'),
- 'required_type': fields.selection([('all','All'), ('at least','At Least'), ('at most','At Most'), ('exactly','Exactly'), ('a range','A Range')], 'Respondent must answer'),
- 'req_ans': fields.integer('#Required Answer'),
- 'maximum_req_ans': fields.integer('Maximum Required Answer'),
- 'minimum_req_ans': fields.integer('Minimum Required Answer'),
- 'req_error_msg': fields.text('Error Message'),
- 'allow_comment': fields.boolean('Allow Comment Field'),
- 'sequence': fields.integer('Sequence'),
- 'tot_resp': fields.function(_calc_response, string="Total Answer"),
- 'survey': fields.related('page_id', 'survey_id', type='many2one', relation='survey', string='Survey'),
- 'descriptive_text': fields.text('Descriptive Text', size=255),
- 'column_heading_ids': fields.one2many('survey.question.column.heading', 'question_id',' Column heading'),
- 'type': fields.selection([('multiple_choice_only_one_ans','Multiple Choice (Only One Answer)'),
- ('multiple_choice_multiple_ans','Multiple Choice (Multiple Answer)'),
- ('matrix_of_choices_only_one_ans','Matrix of Choices (Only One Answers Per Row)'),
- ('matrix_of_choices_only_multi_ans','Matrix of Choices (Multiple Answers Per Row)'),
- ('matrix_of_drop_down_menus','Matrix of Drop-down Menus'),
- ('rating_scale','Rating Scale'),('single_textbox','Single Textbox'),
- ('multiple_textboxes','Multiple Textboxes'),
- ('multiple_textboxes_diff_type','Multiple Textboxes With Different Type'),
- ('comment','Comment/Essay Box'),
- ('numerical_textboxes','Numerical Textboxes'),('date','Date'),
- ('date_and_time','Date and Time'),('descriptive_text','Descriptive Text'),
- ('table','Table'),
- ], 'Question Type', required=1,),
- 'is_comment_require': fields.boolean('Add Comment Field'),
- 'comment_label': fields.char('Field Label', size = 255),
- 'comment_field_type': fields.selection([('char', 'Single Line Of Text'), ('text', 'Paragraph of Text')], 'Comment Field Type'),
- 'comment_valid_type': fields.selection([('do_not_validate', '''Don't Validate Comment Text.'''),
- ('must_be_specific_length', 'Must Be Specific Length'),
- ('must_be_whole_number', 'Must Be A Whole Number'),
- ('must_be_decimal_number', 'Must Be A Decimal Number'),
- ('must_be_date', 'Must Be A Date'),
- ('must_be_email_address', 'Must Be An Email Address'),
- ], 'Text Validation'),
- 'comment_minimum_no': fields.integer('Minimum number'),
- 'comment_maximum_no': fields.integer('Maximum number'),
- 'comment_minimum_float': fields.float('Minimum decimal number'),
- 'comment_maximum_float': fields.float('Maximum decimal number'),
- 'comment_minimum_date': fields.date('Minimum date'),
- 'comment_maximum_date': fields.date('Maximum date'),
- 'comment_valid_err_msg': fields.text('Error message'),
- 'make_comment_field': fields.boolean('Make Comment Field an Answer Choice'),
- 'make_comment_field_err_msg': fields.text('Error message'),
- 'is_validation_require': fields.boolean('Validate Text'),
- 'validation_type': fields.selection([('do_not_validate', '''Don't Validate Comment Text.'''),\
- ('must_be_specific_length', 'Must Be Specific Length'),\
- ('must_be_whole_number', 'Must Be A Whole Number'),\
- ('must_be_decimal_number', 'Must Be A Decimal Number'),\
- ('must_be_date', 'Must Be A Date'),\
- ('must_be_email_address', 'Must Be An Email Address')\
- ], 'Text Validation'),
- 'validation_minimum_no': fields.integer('Minimum number'),
- 'validation_maximum_no': fields.integer('Maximum number'),
- 'validation_minimum_float': fields.float('Minimum decimal number'),
- 'validation_maximum_float': fields.float('Maximum decimal number'),
- 'validation_minimum_date': fields.date('Minimum date'),
- 'validation_maximum_date': fields.date('Maximum date'),
- 'validation_valid_err_msg': fields.text('Error message'),
- 'numeric_required_sum': fields.integer('Sum of all choices'),
- 'numeric_required_sum_err_msg': fields.text('Error message'),
- 'rating_allow_one_column_require': fields.boolean('Allow Only One Answer per Column (Forced Ranking)'),
- 'in_visible_rating_weight': fields.boolean('Is Rating Scale Invisible?'),
- 'in_visible_menu_choice': fields.boolean('Is Menu Choice Invisible?'),
- 'in_visible_answer_type': fields.boolean('Is Answer Type Invisible?'),
- 'comment_column': fields.boolean('Add comment column in matrix'),
- 'column_name': fields.char('Column Name',size=256),
- 'no_of_rows': fields.integer('No of Rows'),
+ # Question metadata
+ 'page_id': fields.many2one('survey.page', 'Survey page',
+ ondelete='cascade', required=1),
+ 'survey_id': fields.related('page_id', 'survey_id', type='many2one',
+ relation='survey.survey', string='Survey'),
+ 'sequence': fields.integer(string='Sequence'),
+
+ # Question
+ 'question': fields.char('Question Name', required=1, translate=True),
+ 'description': fields.html('Description', help="Use this field to add \
+ additional explanations about your question", translate=True,
+ oldname='descriptive_text'),
+
+ # Answer
+ 'type': fields.selection([('free_text', 'Long Text Zone'),
+ ('textbox', 'Text Input'),
+ ('numerical_box', 'Numerical Value'),
+ ('datetime', 'Date and Time'),
+ ('simple_choice', 'Multiple choice: only one answer'),
+ ('multiple_choice', 'Multiple choice: multiple answers allowed'),
+ ('matrix', 'Matrix')], 'Type of Question', required=1),
+ 'matrix_subtype': fields.selection([('simple', 'One choice per row'),
+ ('multiple', 'Multiple choices per row')], 'Matrix Type'),
+ 'labels_ids': fields.one2many('survey.label',
+ 'question_id', 'Types of answers', oldname='answer_choice_ids'),
+ 'labels_ids_2': fields.one2many('survey.label',
+ 'question_id_2', 'Rows of the Matrix'),
+ # labels are used for proposed choices
+ # if question.type == simple choice | multiple choice
+ # -> only labels_ids is used
+ # if question.type == matrix
+ # -> labels_ids are the columns of the matrix
+ # -> labels_ids_2 are the rows of the matrix
+
+ # Display options
+ 'column_nb': fields.selection([('12', '1'),
+ ('6', '2'),
+ ('4', '3'),
+ ('3', '4'),
+ ('2', '6')],
+ 'Number of columns'),
+ # These options refer to col-xx-[12|6|4|3|2] classes in Bootstrap
+ 'display_mode': fields.selection([('columns', 'Radio Buttons/Checkboxes'),
+ ('dropdown', 'Selection Box')],
+ 'Display mode'),
+
+ # Comments
+ 'comments_allowed': fields.boolean('Show Comments Field',
+ oldname="allow_comment"),
+ 'comments_message': fields.char('Comment Message', translate=True),
+ 'comment_count_as_answer': fields.boolean('Comment Field is an Answer Choice',
+ oldname='make_comment_field'),
+
+ # Validation
+ 'validation_required': fields.boolean('Validate entry',
+ oldname='is_validation_require'),
+ 'validation_email': fields.boolean('Input must be an email'),
+ 'validation_length_min': fields.integer('Minimum Text Length'),
+ 'validation_length_max': fields.integer('Maximum Text Length'),
+ 'validation_min_float_value': fields.float('Minimum value'),
+ 'validation_max_float_value': fields.float('Maximum value'),
+ 'validation_min_date': fields.datetime('Minimum Date'),
+ 'validation_max_date': fields.datetime('Maximum Date'),
+ 'validation_error_msg': fields.char('Error message',
+ oldname='validation_valid_err_msg',
+ translate=True),
+
+ # Constraints on number of answers (matrices)
+ 'constr_mandatory': fields.boolean('Mandatory Answer',
+ oldname="is_require_answer"),
+ 'constr_error_msg': fields.char("Error message",
+ oldname='req_error_msg', translate=True),
+ 'user_input_line_ids': fields.one2many('survey.user_input_line',
+ 'question_id', 'Answers',
+ domain=[('skipped', '=', False)]),
+ }
+
+ _defaults = {
+ 'page_id': lambda self, cr, uid, context: context.get('page_id'),
+ 'sequence': 10,
+ 'type': 'free_text',
+ 'matrix_subtype': 'simple',
+ 'column_nb': '12',
+ 'display_mode': 'columns',
+ 'constr_error_msg': lambda s, cr, uid, c: _('This question requires an answer.'),
+ 'validation_error_msg': lambda s, cr, uid, c: _('The answer you entered has an invalid format.'),
+ 'validation_required': False,
+ 'comments_message': lambda s, cr, uid, c: _('If other, precise:'),
+ }
+
+ _sql_constraints = [
+ ('positive_len_min', 'CHECK (validation_length_min >= 0)', 'A length must be positive!'),
+ ('positive_len_max', 'CHECK (validation_length_max >= 0)', 'A length must be positive!'),
+ ('validation_length', 'CHECK (validation_length_min <= validation_length_max)', 'Max length cannot be smaller than min length!'),
+ ('validation_float', 'CHECK (validation_min_float_value <= validation_max_float_value)', 'Max value cannot be smaller than min value!'),
+ ('validation_date', 'CHECK (validation_min_date <= validation_max_date)', 'Max date cannot be smaller than min date!')
+ ]
+
+ def copy_data(self, cr, uid, ids, default=None, context=None):
+ # This will prevent duplication of user input lines in case of question duplication
+ # (in cascade, this will also allow to duplicate surveys without duplicating bad user input
+ # lines)
+ vals = {'user_input_line_ids': []}
+
+ # Updating question title
+ current_rec = self.read(cr, uid, ids, context=context)
+ question = _("%s (copy)") % (current_rec.get('question'))
+ vals['question'] = question
+
+ return super(survey_question, self).copy_data(cr, uid, ids, default=vals,
+ context=context)
+
+ # Validation methods
+
+ def validate_question(self, cr, uid, question, post, answer_tag, context=None):
+ ''' Validate question, depending on question type and parameters '''
+ try:
+ checker = getattr(self, 'validate_' + question.type)
+ except AttributeError:
+ _logger.warning(question.type + ": This type of question has no validation method")
+ return {}
+ else:
+ return checker(cr, uid, question, post, answer_tag, context=context)
+
+ def validate_free_text(self, cr, uid, question, post, answer_tag, context=None):
+ 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
+
+ def validate_textbox(self, cr, uid, question, post, answer_tag, context=None):
+ 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})
+ # Email format validation
+ # Note: this validation is very basic:
+ # all the strings of the form
+ # @.
+ # will be accepted
+ if answer and question.validation_email:
+ if not re.match(r"[^@]+@[^@]+\.[^@]+", answer):
+ errors.update({answer_tag: _('This answer must be an email address')})
+ # Answer validation (if properly defined)
+ # Length of the answer must be in a range
+ if answer and question.validation_required:
+ if not (question.validation_length_min <= len(answer) <= question.validation_length_max):
+ errors.update({answer_tag: question.validation_error_msg})
+ return errors
+
+ def validate_numerical_box(self, cr, uid, question, post, answer_tag, context=None):
+ 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:
+ floatanswer = float(answer)
+ except ValueError:
+ errors.update({answer_tag: _('This is not a number')})
+ # Answer validation (if properly defined)
+ if answer and question.validation_required:
+ # Answer is not in the right range
+ try:
+ floatanswer = float(answer) # check that it is a float has been done hereunder
+ if not (question.validation_min_float_value <= floatanswer <= question.validation_max_float_value):
+ errors.update({answer_tag: question.validation_error_msg})
+ except ValueError:
+ pass
+ return errors
+
+ def validate_datetime(self, cr, uid, question, post, answer_tag, context=None):
+ 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
+ if answer:
+ try:
+ dateanswer = datetime.datetime.strptime(answer, DF)
+ except ValueError:
+ errors.update({answer_tag: _('This is not a date/time')})
+ return errors
+ # Answer validation (if properly defined)
+ if answer and question.validation_required:
+ # Answer is not in the right range
+ try:
+ dateanswer = datetime.datetime.strptime(answer, DF)
+ if not (datetime.datetime.strptime(question.validation_min_date, DF) <= dateanswer <= datetime.datetime.strptime(question.validation_max_date, DF)):
+ errors.update({answer_tag: question.validation_error_msg})
+ except ValueError: # check that it is a datetime has been done hereunder
+ pass
+ return errors
+
+ def validate_simple_choice(self, cr, uid, question, post, answer_tag, context=None):
+ errors = {}
+ if question.comments_allowed:
+ comment_tag = "%s_%s" % (answer_tag, 'comment')
+ # Empty answer to mandatory question
+ if question.constr_mandatory and not answer_tag in post:
+ errors.update({answer_tag: question.constr_error_msg})
+ if question.constr_mandatory and answer_tag in post and post[answer_tag].strip() == '':
+ errors.update({answer_tag: question.constr_error_msg})
+ # 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})
+ return errors
+
+ def validate_multiple_choice(self, cr, uid, question, post, answer_tag, context=None):
+ errors = {}
+ if question.constr_mandatory:
+ answer_candidates = dict_keys_startswith(post, answer_tag)
+ comment_flag = answer_candidates.pop(("%s_%s" % (answer_tag, -1)), None)
+ if question.comments_allowed:
+ comment_answer = answer_candidates.pop(("%s_%s" % (answer_tag, 'comment')), '').strip()
+ # There is no answer neither comments (if comments count as answer)
+ if not answer_candidates and question.comment_count_as_answer and (not comment_flag or not comment_answer):
+ errors.update({answer_tag: question.constr_error_msg})
+ # There is no answer at all
+ if not answer_candidates and not question.comment_count_as_answer:
+ errors.update({answer_tag: question.constr_error_msg})
+ return errors
+
+ def validate_matrix(self, cr, uid, question, post, answer_tag, context=None):
+ errors = {}
+ if question.constr_mandatory:
+ lines_number = len(question.labels_ids_2)
+ answer_candidates = dict_keys_startswith(post, answer_tag)
+ comment_answer = answer_candidates.pop(("%s_%s" % (answer_tag, 'comment')), '').strip()
+ # Number of lines that have been answered
+ if question.matrix_subtype == 'simple':
+ answer_number = len(answer_candidates)
+ elif question.matrix_subtype == 'multiple':
+ answer_number = len(set([sk.rsplit('_', 1)[0] for sk in answer_candidates.keys()]))
+ else:
+ raise RuntimeError("Invalid matrix subtype")
+ # Validate that each line has been answered
+ if answer_number != lines_number:
+ errors.update({answer_tag: question.constr_error_msg})
+ return errors
+
+
+class survey_label(osv.Model):
+ ''' A suggested answer for a question '''
+ _name = 'survey.label'
+ _rec_name = 'value'
+ _order = 'sequence'
+ _description = 'Survey Label'
+
+ def _check_question_not_empty(self, cr, uid, ids, context=None):
+ '''Ensure that field question_id XOR field question_id_2 is not null'''
+ for label in self.browse(cr, uid, ids, context=context):
+ # 'bool()' is required in order to make '!=' act as XOR with objects
+ return bool(label.question_id) != bool(label.question_id_2)
+
+ _columns = {
+ 'question_id': fields.many2one('survey.question', 'Question',
+ ondelete='cascade'),
+ 'question_id_2': fields.many2one('survey.question', 'Question',
+ ondelete='cascade'),
+ 'sequence': fields.integer('Label Sequence order'),
+ 'value': fields.char("Suggested value", translate=True,
+ required=True),
+ 'quizz_mark': fields.float('Score for this answer'),
+ }
+ defaults = {
+ 'sequence': 100,
+ }
+ _constraints = [
+ (_check_question_not_empty, "A label must be attached to one and only one question", ['question_id', 'question_id_2'])
+ ]
+
+
+class survey_user_input(osv.Model):
+ ''' Metadata for a set of one user's answers to a particular survey '''
+ _name = "survey.user_input"
+ _rec_name = 'date_create'
+ _description = 'Survey User Input'
+
+ def _quizz_get_score(self, cr, uid, ids, name, args, context=None):
+ ret = dict()
+ for user_input in self.browse(cr, uid, ids, context=context):
+ ret[user_input.id] = sum([uil.quizz_mark for uil in user_input.user_input_line_ids] or [0.0])
+ return ret
+
+ _columns = {
+ 'survey_id': fields.many2one('survey.survey', 'Survey', required=True,
+ readonly=1, ondelete='restrict'),
+ 'date_create': fields.datetime('Creation Date', required=True,
+ readonly=1),
+ 'deadline': fields.datetime("Deadline",
+ help="Date by which the person can open the survey and submit answers",
+ oldname="date_deadline"),
+ 'type': fields.selection([('manually', 'Manually'), ('link', 'Link')],
+ 'Answer Type', required=1, readonly=1,
+ oldname="response_type"),
+ 'state': fields.selection([('new', 'Not started yet'),
+ ('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),
+
+ # Optional Identification data
+ 'partner_id': fields.many2one('res.partner', 'Partner', readonly=1),
+ 'email': fields.char("E-mail", readonly=1),
+
+ # Displaying data
+ 'last_displayed_page_id': fields.many2one('survey.page',
+ 'Last displayed page'),
+ # The answers !
+ 'user_input_line_ids': fields.one2many('survey.user_input_line',
+ 'user_input_id', 'Answers'),
+
+ # URLs used to display the answers
+ 'result_url': fields.related('survey_id', 'result_url', string="Public link to the survey results"),
+ 'print_url': fields.related('survey_id', 'print_url', string="Public link to the empty survey"),
+
+ 'quizz_score': fields.function(_quizz_get_score, type="float", string="Score for the quiz")
}
_defaults = {
- 'sequence': lambda * a: 1,
- 'type': lambda * a: 'multiple_choice_multiple_ans',
- 'req_error_msg': lambda * a: 'This question requires an answer.',
- 'required_type': lambda * a: 'at least',
- 'req_ans': lambda * a: 1,
- 'comment_field_type': lambda * a: 'char',
- 'comment_label': lambda * a: 'Other (please specify)',
- 'comment_valid_type': lambda * a: 'do_not_validate',
- 'comment_valid_err_msg': lambda * a : 'The comment you entered is in an invalid format.',
- 'validation_type': lambda * a: 'do_not_validate',
- 'validation_valid_err_msg': lambda * a : 'The comment you entered is in an invalid format.',
- 'numeric_required_sum_err_msg': lambda * a :'The choices need to add up to [enter sum here].',
- 'make_comment_field_err_msg': lambda * a : 'Please enter a comment.',
- 'in_visible_answer_type': lambda * a: 1
+ 'date_create': fields.datetime.now,
+ 'type': 'manually',
+ 'state': 'new',
+ 'token': lambda s, cr, uid, c: uuid.uuid4().__str__(),
+ 'quizz_score': 0.0,
}
- def on_change_type(self, cr, uid, ids, type, context=None):
- val = {}
- val['is_require_answer'] = False
- val['is_comment_require'] = False
- val['is_validation_require'] = False
- val['comment_column'] = False
+ _sql_constraints = [
+ ('unique_token', 'UNIQUE (token)', 'A token must be unique!'),
+ ('deadline_in_the_past', 'CHECK (deadline >= date_create)', 'The deadline cannot be in the past')
+ ]
- if type in ['multiple_textboxes_diff_type']:
- val['in_visible_answer_type'] = False
- return {'value': val}
+ def copy_data(self, cr, uid, id, default=None, context=None):
+ raise osv.except_osv(_('Warning!'), _('You cannot duplicate this \
+ element!'))
- if type in ['rating_scale']:
- val.update({'in_visible_rating_weight':False, 'in_visible_menu_choice':True})
- return {'value': val}
+ def do_clean_emptys(self, cr, uid, automatic=False, context=None):
+ ''' Remove empty user inputs that have been created manually
+ (used as a cronjob declared in data/survey_cron.xml) '''
+ empty_user_input_ids = self.search(cr, uid, [('type', '=', 'manually'),
+ ('state', '=', 'new'),
+ ('date_create', '<', (datetime.datetime.now() - datetime.timedelta(hours=1)).strftime(DF))],
+ context=context)
+ if empty_user_input_ids:
+ self.unlink(cr, uid, empty_user_input_ids, context=context)
- elif type in ['matrix_of_drop_down_menus']:
- val.update({'in_visible_rating_weight':True, 'in_visible_menu_choice':False})
- return {'value': val}
+ def action_survey_resent(self, cr, uid, ids, context=None):
+ ''' Sent again the invitation '''
+ record = self.browse(cr, uid, ids[0], context=context)
+ context = context or {}
+ context.update({
+ 'survey_resent_token': True,
+ 'default_partner_ids': record.partner_id and [record.partner_id.id] or [],
+ 'default_multi_email': record.email or "",
+ 'default_public': 'email_private',
+ })
+ return self.pool.get('survey.survey').action_send_survey(cr, uid,
+ [record.survey_id.id], context=context)
- elif type in ['single_textbox']:
- val.update({'in_visible_rating_weight':True, 'in_visible_menu_choice':True})
- return {'value': val}
-
- else:
- val.update({'in_visible_rating_weight':True, 'in_visible_menu_choice':True,\
- 'in_visible_answer_type':True})
- return {'value': val}
-
- 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', 'column_heading_ids', 'page_id', 'question'])
- for question in questions:
- col_len = len(question['column_heading_ids'])
- if vals.has_key('column_heading_ids'):
- for col in vals['column_heading_ids']:
- if type(col[2]) == type({}):
- col_len += 1
- else:
- col_len -= 1
-
- if vals.has_key('type'):
- que_type = vals['type']
- else:
- que_type = question['type']
-
- if que_type in ['matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans',\
- 'matrix_of_drop_down_menus', 'rating_scale']:
- if not col_len:
- raise osv.except_osv(_('Warning!'),_('You must enter one or more column headings for question "%s" of page %s.') % (question['question'], question['page_id'][1]))
- ans_len = len(question['answer_choice_ids'])
-
- if vals.has_key('answer_choice_ids'):
- for ans in vals['answer_choice_ids']:
- if type(ans[2]) == type({}):
- ans_len += 1
- else:
- ans_len -= 1
-
- if que_type not in ['descriptive_text', 'single_textbox', 'comment','table']:
- if not ans_len:
- raise osv.except_osv(_('Warning!'),_('You must enter one or more Answers for question "%s" of page %s.') % (question['question'], question['page_id'][1]))
- req_type = ""
-
- if vals.has_key('required_type'):
- req_type = vals['required_type']
- else:
- req_type = question['required_type']
-
- if que_type in ['multiple_choice_multiple_ans','matrix_of_choices_only_one_ans', \
- 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus',\
- 'rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time']:
- if req_type in ['at least', 'at most', 'exactly']:
- if vals.has_key('req_ans'):
- if not vals['req_ans'] or vals['req_ans'] > ans_len:
- raise osv.except_osv(_('Warning!'),_("#Required Answer you entered \
- is greater than the number of answer. \
- Please use a number that is smaller than %d.") % (ans_len + 1))
- else:
- if not question['req_ans'] or question['req_ans'] > ans_len:
- raise osv.except_osv(_('Warning!'),_("#Required Answer you entered is \
- greater than the number of answer.\
- Please use a number that is smaller than %d.") % (ans_len + 1))
-
- if req_type == 'a range':
- minimum_ans = 0
- maximum_ans = 0
- if vals.has_key('minimum_req_ans'):
- minimum_ans = vals['minimum_req_ans']
- if not vals['minimum_req_ans'] or vals['minimum_req_ans'] > ans_len:
- raise osv.except_osv(_('Warning!'),_("Minimum Required Answer\
- you entered is greater than the number of answer.\
- Please use a number that is smaller than %d.") % (ans_len + 1))
- else:
- minimum_ans = question['minimum_req_ans']
- if not question['minimum_req_ans'] or question['minimum_req_ans'] > ans_len:
- raise osv.except_osv(_('Warning!'),_("Minimum Required Answer you\
- entered is greater than the number of answer. \
- Please use a number that is smaller than %d.") % (ans_len + 1))
- if vals.has_key('maximum_req_ans'):
- maximum_ans = vals['maximum_req_ans']
- if not vals['maximum_req_ans'] or vals['maximum_req_ans'] > ans_len:
- raise osv.except_osv(_('Warning!'),_("Maximum Required Answer you \
- entered for your maximum is greater than the number of answer.\
- Please use a number that is smaller than %d.") % (ans_len + 1))
- else:
- maximum_ans = question['maximum_req_ans']
- if not question['maximum_req_ans'] or question['maximum_req_ans'] > ans_len:
- raise osv.except_osv(_('Warning!'),_("Maximum Required Answer you\
- entered for your maximum is greater than the number of answer.\
- Please use a number that is smaller than %d.") % (ans_len + 1))
- if maximum_ans <= minimum_ans:
- raise osv.except_osv(_('Warning!'),_("Maximum Required Answer is greater \
- than Minimum Required Answer"))
-
- if question['type'] == 'matrix_of_drop_down_menus' and vals.has_key('column_heading_ids'):
- for col in vals['column_heading_ids']:
- if not col[2] or not col[2].has_key('menu_choice') or not col[2]['menu_choice']:
- raise osv.except_osv(_('Warning!'),_("You must enter one or more menu choices\
- in column heading."))
- elif not col[2] or not col[2].has_key('menu_choice') or\
- col[2]['menu_choice'].strip() == '':
- raise osv.except_osv(_('Warning!'),_("You must enter one or more menu \
- choices in column heading (white spaces not allowed)."))
-
- return super(survey_question, self).write(cr, uid, ids, vals, context=context)
-
- def create(self, cr, uid, vals, context=None):
- minimum_ans = 0
- maximum_ans = 0
- page = self.pool.get('survey.page').browse(cr, uid, int(vals.get('page_id', 0)), context=context).title
- if vals.has_key('answer_choice_ids') and not len(vals['answer_choice_ids']):
- if vals.has_key('type') and vals['type'] not in ['descriptive_text', 'single_textbox', 'comment','table']:
- raise osv.except_osv(_('Warning!'),_('You must enter one or more answers for question "%s" of page %s .') % (vals['question'], page))
-
- if vals.has_key('column_heading_ids') and not len(vals['column_heading_ids']):
- if vals.has_key('type') and vals['type'] in ['matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale']:
- raise osv.except_osv(_('Warning!'),_('You must enter one or more column headings for question "%s" of page %s.')% (vals['question'], page))
-
- if vals['type'] in ['multiple_choice_multiple_ans','matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time']:
- if vals.has_key('is_require_answer') and vals.has_key('required_type') and vals['required_type'] in ['at least', 'at most', 'exactly']:
- if vals.has_key('answer_choice_ids') and vals['req_ans'] > len(vals['answer_choice_ids']) or not vals['req_ans']:
- raise osv.except_osv(_('Warning!'),_("#Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d.") % (len(vals['answer_choice_ids'])+1))
-
- if vals.has_key('is_require_answer') and vals.has_key('required_type') and vals['required_type'] == 'a range':
- minimum_ans = vals['minimum_req_ans']
- maximum_ans = vals['maximum_req_ans']
- if vals.has_key('answer_choice_ids') or vals['minimum_req_ans'] > len(vals['answer_choice_ids']) or not vals['minimum_req_ans']:
- raise osv.except_osv(_('Warning!'),_("Minimum Required Answer you entered is greater than the number of answer. Please use a number that is smaller than %d.") % (len(vals['answer_choice_ids'])+1))
- if vals.has_key('answer_choice_ids') or vals['maximum_req_ans'] > len(vals['answer_choice_ids']) or not vals['maximum_req_ans']:
- raise osv.except_osv(_('Warning!'),_("Maximum Required Answer you entered for your maximum is greater than the number of answer. Please use a number that is smaller than %d.") % (len(vals['answer_choice_ids'])+1))
- if maximum_ans <= minimum_ans:
- raise osv.except_osv(_('Warning!'),_("Maximum Required Answer is greater than Minimum Required Answer."))
-
- if vals['type'] == 'matrix_of_drop_down_menus':
- for col in vals['column_heading_ids']:
- if not col[2] or not col[2].has_key('menu_choice') or not col[2]['menu_choice']:
- raise osv.except_osv(_('Warning!'),_("You must enter one or more menu choices in column heading."))
- elif not col[2] or not col[2].has_key('menu_choice') or col[2]['menu_choice'].strip() == '':
- raise osv.except_osv(_('Warning!'),_("You must enter one or more menu choices in column heading (white spaces not allowed)."))
-
- res = super(survey_question, self).create(cr, uid, vals, context)
- return res
-
- def survey_save(self, cr, uid, ids, context=None):
- if context is None:
- context = {}
- search_obj = self.pool.get('ir.ui.view')
- search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
- surv_name_wiz = self.pool.get('survey.name.wiz')
- surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page_no' : context.get('page_number',False) })
+ def action_view_answers(self, cr, uid, ids, context=None):
+ ''' Open the website page with the survey form '''
+ user_input = self.read(cr, uid, ids, ['print_url', 'token'], context=context)[0]
return {
- 'view_type': 'form',
- 'view_mode': 'form',
- 'res_model': 'survey.question.wiz',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'search_view_id': search_id[0],
- 'context': context
+ 'type': 'ir.actions.act_url',
+ 'name': "View Answers",
+ 'target': 'self',
+ 'url': '%s/%s' % (user_input['print_url'], user_input['token'])
}
- def default_get(self, cr, uid, fields, context=None):
- if context is None:
- context = {}
- data = super(survey_question, self).default_get(cr, uid, fields, context)
- if context.has_key('page_id'):
- data['page_id']= context.get('page_id', False)
- return data
+ def action_survey_results(self, cr, uid, ids, context=None):
+ ''' Open the website page with the survey results '''
+ return {
+ 'type': 'ir.actions.act_url',
+ 'name': "Survey Results",
+ 'target': 'self',
+ 'url': self.read(cr, uid, ids, ['result_url'], context=context)[0]['result_url']
+ }
-
-class survey_question_column_heading(osv.osv):
- _name = 'survey.question.column.heading'
- _description = 'Survey Question Column Heading'
- _rec_name = 'title'
-
- def _get_in_visible_rating_weight(self, cr, uid, context=None):
- if context is None:
- context = {}
- if context.get('in_visible_rating_weight', False):
- return context['in_visible_rating_weight']
- return False
- def _get_in_visible_menu_choice(self,cr, uid, context=None):
- if context is None:
- context = {}
- if context.get('in_visible_menu_choice', False):
- return context['in_visible_menu_choice']
- return False
-
- _columns = {
- 'title': fields.char('Column Heading', size=128, required=1),
- 'menu_choice': fields.text('Menu Choice'),
- 'rating_weight': fields.integer('Weight'),
- 'question_id': fields.many2one('survey.question', 'Question', ondelete='cascade'),
- 'in_visible_rating_weight': fields.boolean('Is Rating Scale Invisible ??'),
- 'in_visible_menu_choice': fields.boolean('Is Menu Choice Invisible??')
- }
- _defaults={
- 'in_visible_rating_weight': _get_in_visible_rating_weight,
- 'in_visible_menu_choice': _get_in_visible_menu_choice,
- }
-
-class survey_answer(osv.osv):
- _name = 'survey.answer'
- _description = 'Survey Answer'
- _rec_name = 'answer'
- _order = 'sequence'
-
- def _calc_response_avg(self, cr, uid, ids, field_name, arg, context=None):
- val = {}
- for rec in self.browse(cr, uid, ids, context=context):
- cr.execute("select count(question_id) ,(select count(answer_id) \
- from survey_response_answer sra, survey_response_line sa \
- where sra.response_id = sa.id and sra.answer_id = %d \
- and sa.state='done') as tot_ans from survey_response_line \
- where question_id = %d and state = 'done'"\
- % (rec.id, rec.question_id.id))
- res = cr.fetchone()
- if res[0]:
- avg = float(res[1]) * 100 / res[0]
- else:
- avg = 0.0
- val[rec.id] = {
- 'response': res[1],
- 'average': round(avg, 2),
- }
- return val
-
- def _get_in_visible_answer_type(self, cr, uid, context=None):
- if context is None:
- context = {}
- return context.get('in_visible_answer_type', False)
-
- _columns = {
- 'question_id': fields.many2one('survey.question', 'Question', ondelete='cascade'),
- 'answer': fields.char('Answer', size=128, required=1),
- 'sequence': fields.integer('Sequence'),
- 'response': fields.function(_calc_response_avg, string="#Answer", multi='sums'),
- 'average': fields.function(_calc_response_avg, string="#Avg", multi='sums'),
- 'type': fields.selection([('char','Character'),('date','Date'),('datetime','Date & Time'),\
- ('integer','Integer'),('float','Float'),('selection','Selection'),\
- ('email','Email')], "Type of Answer",required=1),
- 'menu_choice': fields.text('Menu Choices'),
- 'in_visible_answer_type': fields.boolean('Is Answer Type Invisible??')
- }
- _defaults = {
-# 'sequence' : lambda * a: 1,
- 'type' : lambda * a: 'char',
- 'in_visible_answer_type':_get_in_visible_answer_type,
- }
-
- def default_get(self, cr, uid, fields, context=None):
- if context is None:
- context = {}
- data = super(survey_answer, self).default_get(cr, uid, fields, context)
- return data
-
-
-class survey_response(osv.osv):
- _name = "survey.response"
+class survey_user_input_line(osv.Model):
+ _name = 'survey.user_input_line'
+ _description = 'Survey User Input Line'
_rec_name = 'date_create'
+
+ def _answered_or_skipped(self, cr, uid, ids, context=None):
+ for uil in self.browse(cr, uid, ids, context=context):
+ # 'bool()' is required in order to make '!=' act as XOR with objects
+ return uil.skipped != bool(uil.answer_type)
+
+ def _check_answer_type(self, cr, uid, ids, context=None):
+ for uil in self.browse(cr, uid, ids, context=None):
+ if uil.answer_type:
+ if uil.answer_type == 'text':
+ # 'bool()' is required in order to make '!=' act as XOR with objects
+ return bool(uil.value_text)
+ elif uil.answer_type == 'number':
+ return (uil.value_number == 0) or (uil.value_number != False)
+ elif uil.answer_type == 'date':
+ return bool(uil.value_date)
+ elif uil.answer_type == 'free_text':
+ return bool(uil.value_free_text)
+ elif uil.answer_type == 'suggestion':
+ return bool(uil.value_suggested)
+ return True
+
_columns = {
- 'survey_id' : fields.many2one('survey', 'Survey', required=1, ondelete='cascade'),
- 'date_create' : fields.datetime('Create Date', required=1),
- 'user_id' : fields.many2one('res.users', 'User'),
- 'response_type' : fields.selection([('manually', 'Manually'), ('link', 'Link')], \
- 'Answer Type', required=1, readonly=1),
- 'question_ids' : fields.one2many('survey.response.line', 'response_id', 'Answer'),
- 'state' : fields.selection([('done', 'Finished '),('skip', 'Not Finished')], \
- 'Status', readonly=True),
- }
- _defaults = {
- 'state' : lambda * a: "skip",
- 'response_type' : lambda * a: "manually",
- }
-
- def name_get(self, cr, uid, ids, context=None):
- if not len(ids):
- return []
- reads = self.read(cr, uid, ids, ['user_id','date_create'], context=context)
- res = []
- for record in reads:
- name = (record['user_id'] and record['user_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 the resource!'))
-
-
-class survey_response_line(osv.osv):
- _name = 'survey.response.line'
- _description = 'Survey Response Line'
- _rec_name = 'date_create'
- _columns = {
- 'response_id': fields.many2one('survey.response', 'Answer', ondelete='cascade'),
+ 'user_input_id': fields.many2one('survey.user_input', 'User Input',
+ ondelete='cascade', required=1),
+ 'question_id': fields.many2one('survey.question', 'Question',
+ ondelete='restrict', required=1),
+ 'page_id': fields.related('question_id', 'page_id', type='many2one',
+ relation='survey.page', string="Page"),
+ 'survey_id': fields.related('user_input_id', 'survey_id',
+ type="many2one", relation="survey.survey",
+ string='Survey', store=True),
'date_create': fields.datetime('Create Date', required=1),
- 'state': fields.selection([('draft', 'Draft'), ('done', 'Answered'),('skip', 'Skiped')],\
- 'Status', readonly=True),
- 'question_id': fields.many2one('survey.question', 'Question'),
- 'page_id': fields.related('question_id', 'page_id', type='many2one', \
- relation='survey.page', string='Page'),
- 'response_answer_ids': fields.one2many('survey.response.answer', 'response_id', 'Answer'),
- 'response_table_ids': fields.one2many('survey.tbl.column.heading', \
- 'response_table_id', 'Answer'),
- 'comment': fields.text('Notes'),
- 'single_text': fields.char('Text', size=255),
+ 'skipped': fields.boolean('Skipped'),
+ 'answer_type': fields.selection([('text', 'Text'),
+ ('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"),
+ 'value_free_text': fields.text("Free Text answer"),
+ 'value_suggested': fields.many2one('survey.label', "Suggested answer"),
+ 'value_suggested_row': fields.many2one('survey.label', "Row answer"),
+ 'quizz_mark': fields.float("Score given for this answer")
}
+
_defaults = {
- 'state' : lambda * a: "draft",
+ 'skipped': False,
+ 'date_create': fields.datetime.now()
}
+ _constraints = [
+ (_answered_or_skipped, "A question cannot be unanswered and skipped", ['skipped', 'answer_type']),
+ (_check_answer_type, "The answer must be in the right type", ['answer_type', 'text', 'number', 'date', 'free_text', 'suggestion'])
+ ]
+ def __get_mark(self, cr, uid, value_suggested, context=None):
+ try:
+ mark = self.pool.get('survey.label').browse(cr, uid, int(value_suggested), context=context).quizz_mark
+ except KeyError:
+ mark = 0.0
+ except ValueError:
+ mark = 0.0
+ return mark
-class survey_tbl_column_heading(osv.osv):
- _name = 'survey.tbl.column.heading'
- _order = 'name'
- _columns = {
- 'name': fields.integer('Row Number'),
- 'column_id': fields.many2one('survey.question.column.heading', 'Column'),
- 'value': fields.char('Value', size = 255),
- 'response_table_id': fields.many2one('survey.response.line', 'Answer', ondelete='cascade'),
- }
+ def create(self, cr, uid, vals, context=None):
+ value_suggested = vals.get('value_suggested')
+ if value_suggested:
+ vals.update({'quizz_mark': self.__get_mark(cr, uid, value_suggested)})
+ return super(survey_user_input_line, self).create(cr, uid, vals, context=context)
+ def write(self, cr, uid, ids, vals, context=None):
+ value_suggested = vals.get('value_suggested')
+ if value_suggested:
+ vals.update({'quizz_mark': self.__get_mark(cr, uid, value_suggested)})
+ return super(survey_user_input_line, self).write(cr, uid, ids, vals, context=context)
-class survey_response_answer(osv.osv):
- _name = 'survey.response.answer'
- _description = 'Survey Answer'
- _rec_name = 'response_id'
- _columns = {
- 'response_id': fields.many2one('survey.response.line', 'Answer', ondelete='cascade'),
- 'answer_id': fields.many2one('survey.answer', 'Answer', required=1, ondelete='cascade'),
- 'column_id': fields.many2one('survey.question.column.heading','Column'),
- 'answer': fields.char('Value', size =255),
- 'value_choice': fields.char('Value Choice', size =255),
- 'comment': fields.text('Notes'),
- 'comment_field': fields.char('Comment', size = 255)
- }
+ def copy_data(self, cr, uid, id, default=None, context=None):
+ raise osv.except_osv(_('Warning!'), _('You cannot duplicate this \
+ element!'))
+ def save_lines(self, cr, uid, user_input_id, question, post, answer_tag,
+ context=None):
+ ''' Save answers to questions, depending on question type
-class res_users(osv.osv):
- _inherit = "res.users"
- _name = "res.users"
- _columns = {
- 'survey_id': fields.many2many('survey', 'survey_users_rel', 'uid', 'sid', 'Groups'),
- }
+ If an answer already exists for question and user_input_id, it will be
+ overwritten (in order to maintain data consistency). '''
+ try:
+ saver = getattr(self, 'save_line_' + question.type)
+ except AttributeError:
+ _logger.error(question.type + ": This type of question has no saving function")
+ return False
+ else:
+ saver(cr, uid, user_input_id, question, post, answer_tag, context=context)
-
-class survey_request(osv.osv):
- _name = "survey.request"
- _order = 'date_deadline'
- _rec_name = 'date_deadline'
- _columns = {
- 'date_deadline': fields.date("Deadline date"),
- 'user_id': fields.many2one("res.users", "User"),
- 'email': fields.char("Email", size=64),
- 'survey_id': fields.many2one("survey", "Survey", required=1, ondelete='cascade'),
- 'response': fields.many2one('survey.response', 'Answer'),
- 'state': fields.selection([('draft','Draft'),('cancel', 'Cancelled'),('waiting_answer', 'Waiting Answer'),('done', 'Done')], 'Status', readonly=1)
- }
- _defaults = {
- 'state': lambda * a: 'draft',
-# 'date_deadline': lambda * a : (datetime.now() + relativedelta(months=+1)).strftime("%Y-%m-%d %H:%M:%S")
- }
- def survey_req_waiting_answer(self, cr, uid, ids, arg):
- self.write(cr, uid, ids, { 'state' : 'waiting_answer'})
+ def save_line_free_text(self, cr, uid, user_input_id, question, post, answer_tag, context=None):
+ vals = {
+ 'user_input_id': user_input_id,
+ 'question_id': question.id,
+ 'page_id': question.page_id.id,
+ 'survey_id': question.survey_id.id,
+ 'skipped': False,
+ }
+ if answer_tag in post and post[answer_tag].strip() != '':
+ vals.update({'answer_type': 'free_text', 'value_free_text': post[answer_tag]})
+ else:
+ vals.update({'answer_type': None, 'skipped': True})
+ old_uil = self.search(cr, uid, [('user_input_id', '=', user_input_id),
+ ('survey_id', '=', question.survey_id.id),
+ ('question_id', '=', question.id)],
+ context=context)
+ if old_uil:
+ self.write(cr, uid, old_uil[0], vals, context=context)
+ else:
+ self.create(cr, uid, vals, context=context)
return True
- def survey_req_draft(self, cr, uid, ids, arg):
- self.write(cr, uid, ids, { 'state' : 'draft'})
+ def save_line_textbox(self, cr, uid, user_input_id, question, post, answer_tag, context=None):
+ vals = {
+ 'user_input_id': user_input_id,
+ 'question_id': question.id,
+ 'page_id': question.page_id.id,
+ 'survey_id': question.survey_id.id,
+ 'skipped': False
+ }
+ if answer_tag in post and post[answer_tag].strip() != '':
+ vals.update({'answer_type': 'text', 'value_text': post[answer_tag]})
+ else:
+ vals.update({'answer_type': None, 'skipped': True})
+ old_uil = self.search(cr, uid, [('user_input_id', '=', user_input_id),
+ ('survey_id', '=', question.survey_id.id),
+ ('question_id', '=', question.id)],
+ context=context)
+ if old_uil:
+ self.write(cr, uid, old_uil[0], vals, context=context)
+ else:
+ self.create(cr, uid, vals, context=context)
return True
- def survey_req_done(self, cr, uid, ids, arg):
- self.write(cr, uid, ids, { 'state' : 'done'})
+ def save_line_numerical_box(self, cr, uid, user_input_id, question, post, answer_tag, context=None):
+ vals = {
+ 'user_input_id': user_input_id,
+ 'question_id': question.id,
+ 'page_id': question.page_id.id,
+ 'survey_id': question.survey_id.id,
+ 'skipped': False
+ }
+ if answer_tag in post and post[answer_tag].strip() != '':
+ vals.update({'answer_type': 'number', 'value_number': float(post[answer_tag])})
+ else:
+ vals.update({'answer_type': None, 'skipped': True})
+ old_uil = self.search(cr, uid, [('user_input_id', '=', user_input_id),
+ ('survey_id', '=', question.survey_id.id),
+ ('question_id', '=', question.id)],
+ context=context)
+ if old_uil:
+ self.write(cr, uid, old_uil[0], vals, context=context)
+ else:
+ self.create(cr, uid, vals, context=context)
return True
- def survey_req_cancel(self, cr, uid, ids, arg):
- self.write(cr, uid, ids, { 'state' : 'cancel'})
+ def save_line_datetime(self, cr, uid, user_input_id, question, post, answer_tag, context=None):
+ vals = {
+ 'user_input_id': user_input_id,
+ 'question_id': question.id,
+ 'page_id': question.page_id.id,
+ 'survey_id': question.survey_id.id,
+ 'skipped': False
+ }
+ if answer_tag in post and post[answer_tag].strip() != '':
+ vals.update({'answer_type': 'date', 'value_date': post[answer_tag]})
+ else:
+ vals.update({'answer_type': None, 'skipped': True})
+ old_uil = self.search(cr, uid, [('user_input_id', '=', user_input_id),
+ ('survey_id', '=', question.survey_id.id),
+ ('question_id', '=', question.id)],
+ context=context)
+ if old_uil:
+ self.write(cr, uid, old_uil[0], vals, context=context)
+ else:
+ self.create(cr, uid, vals, context=context)
return True
- def on_change_user(self, cr, uid, ids, user_id, context=None):
- if user_id:
- user_obj = self.pool.get('res.users')
- user = user_obj.browse(cr, uid, user_id, context=context)
- return {'value': {'email': user.email}}
- return {}
+ def save_line_simple_choice(self, cr, uid, user_input_id, question, post, answer_tag, context=None):
+ vals = {
+ 'user_input_id': user_input_id,
+ 'question_id': question.id,
+ 'page_id': question.page_id.id,
+ 'survey_id': question.survey_id.id,
+ 'skipped': False
+ }
+ old_uil = self.search(cr, uid, [('user_input_id', '=', user_input_id),
+ ('survey_id', '=', question.survey_id.id),
+ ('question_id', '=', question.id)],
+ context=context)
+ if old_uil:
+ self.unlink(cr, uid, old_uil, context=context)
+
+ if answer_tag in post and post[answer_tag].strip() != '':
+ vals.update({'answer_type': 'suggestion', 'value_suggested': post[answer_tag]})
+ else:
+ vals.update({'answer_type': None, 'skipped': True})
+ self.create(cr, uid, vals, context=context)
+
+ comment_answer = post.pop(("%s_%s" % (answer_tag, 'comment')), '').strip()
+ if comment_answer:
+ vals.update({'answer_type': 'text', 'value_text': comment_answer})
+ self.create(cr, uid, vals, context=context)
+
+ return True
+
+ def save_line_multiple_choice(self, cr, uid, user_input_id, question, post, answer_tag, context=None):
+ vals = {
+ 'user_input_id': user_input_id,
+ 'question_id': question.id,
+ 'page_id': question.page_id.id,
+ 'survey_id': question.survey_id.id,
+ 'skipped': False
+ }
+ old_uil = self.search(cr, uid, [('user_input_id', '=', user_input_id),
+ ('survey_id', '=', question.survey_id.id),
+ ('question_id', '=', question.id)],
+ context=context)
+ if old_uil:
+ self.unlink(cr, uid, old_uil, context=context)
+
+ ca = dict_keys_startswith(post, answer_tag)
+ comment_answer = ca.pop(("%s_%s" % (answer_tag, 'comment')), '').strip()
+ if len(ca) > 0:
+ for a in ca:
+ vals.update({'answer_type': 'suggestion', 'value_suggested': ca[a]})
+ self.create(cr, uid, vals, context=context)
+ if comment_answer:
+ vals.update({'answer_type': 'text', 'value_text': comment_answer})
+ self.create(cr, uid, vals, context=context)
+ if not ca and not comment_answer:
+ vals.update({'answer_type': None, 'skipped': True})
+ self.create(cr, uid, vals, context=context)
+ return True
+
+ def save_line_matrix(self, cr, uid, user_input_id, question, post, answer_tag, context=None):
+ vals = {
+ 'user_input_id': user_input_id,
+ 'question_id': question.id,
+ 'page_id': question.page_id.id,
+ 'survey_id': question.survey_id.id,
+ 'skipped': False
+ }
+ old_uil = self.search(cr, uid, [('user_input_id', '=', user_input_id),
+ ('survey_id', '=', question.survey_id.id),
+ ('question_id', '=', question.id)],
+ context=context)
+ if old_uil:
+ self.unlink(cr, uid, old_uil, context=context)
+
+ no_answers = True
+ ca = dict_keys_startswith(post, answer_tag)
+
+ comment_answer = ca.pop(("%s_%s" % (answer_tag, 'comment')), '').strip()
+ if comment_answer:
+ vals.update({'answer_type': 'text', 'value_text': comment_answer})
+ self.create(cr, uid, vals, context=context)
+ no_answers = False
+
+ if question.matrix_subtype == 'simple':
+ for row in question.labels_ids_2:
+ a_tag = "%s_%s" % (answer_tag, row.id)
+ if a_tag in ca:
+ no_answers = False
+ vals.update({'answer_type': 'suggestion', 'value_suggested': ca[a_tag], 'value_suggested_row': row.id})
+ self.create(cr, uid, vals, context=context)
+
+ elif question.matrix_subtype == 'multiple':
+ for col in question.labels_ids:
+ for row in question.labels_ids_2:
+ a_tag = "%s_%s_%s" % (answer_tag, row.id, col.id)
+ if a_tag in ca:
+ no_answers = False
+ vals.update({'answer_type': 'suggestion', 'value_suggested': col.id, 'value_suggested_row': row.id})
+ self.create(cr, uid, vals, context=context)
+ if no_answers:
+ vals.update({'answer_type': None, 'skipped': True})
+ self.create(cr, uid, vals, context=context)
+ return True
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+def dict_keys_startswith(dictionary, string):
+ '''Returns a dictionary containing the elements of whose keys start
+ with .
+
+ .. note::
+ This function uses dictionary comprehensions (Python >= 2.7)'''
+ return {k: dictionary[k] for k in filter(lambda key: key.startswith(string), dictionary.keys())}
diff --git a/addons/survey/survey_data.xml b/addons/survey/survey_data.xml
deleted file mode 100644
index 7627c5d54b0..00000000000
--- a/addons/survey/survey_data.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
- Human Resources
- Human Resources
-
-
- Customer Feeback
- Customer Feeback
-
-
- Supplier Selection
- Supplier Selection
-
-
-
diff --git a/addons/survey/survey_demo.xml b/addons/survey/survey_demo.xml
deleted file mode 100644
index 6f89095c699..00000000000
--- a/addons/survey/survey_demo.xml
+++ /dev/null
@@ -1,3531 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- Initial Partner Feedback
-
- 20
-
- open
- 5
- 1
- 1
- 5
-
-
-
-
- Who are you?
-
-
-
-
-
- What is your company's name?
-
- single_textbox
- 1
- 1
-
- 1
-
-
-
- What is your company's size?
-
- multiple_choice_only_one_ans
-
- 1
-
-
-
- 1
- 1 - 10
-
-
-
-
- 1
- 11 - 50
-
-
-
-
- 1
- 51 - 100
-
-
-
-
- 1
- 101 - 250
-
-
-
-
- 1
- 251 - 500
-
-
-
-
- 1
- 501 - 1000
-
-
-
-
- 1
- > 1000
-
-
-
-
-
-
-
-
- Contracts
-
-
-
-
-
- 1
- Which maintenance contract do you sell to your customers?
-
- multiple_choice_only_one_ans
-
-
-
-
- 1
- OpenERP maintenance contract
-
-
-
-
- 1
- Your own contract, but you buy an OpenERP one
-
-
-
-
- 1
- Your own contract without buying an OpenERP one
-
-
-
-
-
- 1
- When do you propose a maintenance contract to your customers?
-
- multiple_choice_only_one_ans
- text
- Why?
-
- True
-
-
-
- 1
- With each integration
-
-
-
-
- 1
- Sometimes
-
-
-
-
- 1
- Never...
-
-
-
-
-
-
-
-
-
- OpenERP Partner Feedback
-
- 20
-
- open
- 1
- 1
- 5
-
-
-
-
- Who are you?
-
-
-
-
-
- What is your company's name?
-
- single_textbox
- 1
-
- 1
-
-
-
- What is your company's size?
-
- multiple_choice_only_one_ans
-
- 1
-
-
-
- 1
- 1 - 10
-
-
-
-
- 1
- 11 - 50
-
-
-
-
- 1
- 51 - 100
-
-
-
-
- 1
- 101 - 250
-
-
-
-
- 1
- 251 - 500
-
-
-
-
- 1
- 501 - 1000
-
-
-
-
- 1
- > 1000
-
-
-
-
-
-
-
-
- 1
- Where are you located?
-
- multiple_choice_multiple_ans
-
-
-
- 1
- Europe
-
-
-
-
- 1
- North America
-
-
-
-
- 1
- Asia
-
-
-
-
- 1
- South America
-
-
-
-
- 1
- Australia
-
-
-
-
- at least
-
- This question requires an answer.
-
-
-
- 1
- When did you become an OpenERP official partner?
-
- multiple_choice_only_one_ans
-
-
-
- 1
- in 2009
-
-
-
-
- 1
- in 2008
-
-
-
-
- 1
- in 2007
-
-
-
-
- 1
- in 2006
-
-
-
-
- 1
- before 2006
-
-
-
-
-
-
-
-
- 1
- What kind of solutions do you sell to your customers?
-
- multiple_choice_multiple_ans
-
-
-
- 1
- Integrations without specific developments
-
-
-
-
- 1
- Integrations with specific developments
-
-
-
-
- 1
- Odoo Saas Offer
-
-
-
-
-
-
- Contracts
-
-
-
-
-
- 1
- What do you think about the partnership contract?
-
- multiple_choice_only_one_ans
-
-
-
- 1
- Ambiguous
-
-
-
-
- 1
- Not clear enough
-
-
-
-
- 1
- Clear
-
-
-
-
- 1
- Very Clear
-
-
-
-
-
-
-
-
- 1
- When do you propose a maintenance contract to your customers?
-
- multiple_choice_only_one_ans
- text
- Why?
-
- True
-
-
- 1
- With each integration
-
-
-
-
- 1
- Sometimes
-
-
-
-
- 1
- Never...
-
-
-
-
-
-
-
-
- 1
- Which maintenance contract do you sell to your customers.
-
- multiple_choice_only_one_ans
-
-
-
-
- 1
- OpenERP maintenance contract
-
-
-
-
- 1
- Your own contract, but you buy an OpenERP one
-
-
-
-
- 1
- Your own contract without buying an OpenERP one
-
-
-
-
-
-
-
-
- Communication
-
-
-
-
-
- 1
- Give your opinion about Launchpad reporting :
-
- matrix_of_choices_only_one_ans
-
-
-
-
- 1
- Is Launchpad easy to find in OpenObject website?
-
-
-
-
- 1
- Is it easy to report a bug or a blueprint?
-
-
-
-
- 1
- Is it easy to add or modify a translation?
-
-
-
-
- Not at all
-
- 1
- 1
-
-
- No
-
- 1
- 1
-
-
- Yes, but could be better
-
- 1
- 1
-
-
- Absolutely
-
- 1
- 1
-
-
- 1
- Leads
-
- matrix_of_choices_only_one_ans
-
-
-
- 1
- Is Launchpad easy to find in OpenObject website?
-
-
-
-
- 1
- How are the leads that you find thanks to OpenERP SA be converted in customers?
-
-
-
-
- I didn't try, I don't need new leads
-
- 1
- 1
-
-
- Hard
-
- 1
- 1
-
-
- Difficult
-
- 1
- 1
-
-
- Easy
-
- 1
- 1
-
-
- Very Easy
-
- 1
- 1
-
-
-
- 1
- How is OpenERP SA's communication with partners about...
-
- matrix_of_choices_only_one_ans
-
-
-
-
- 1
- Maintenance contracts
-
-
-
-
- 1
- Leads
-
-
-
-
- 1
- Training sessions
-
-
-
-
- Very Bad
-
- 1
- 1
-
-
- Bad
-
- 1
- 1
-
-
- Good
-
- 1
- 1
-
-
- Very Good
-
- 1
- 1
-
-
- 1
- at least
-
- This question requires an answer.
-
-
-
- 1
- In your opinion, how could OpenERP SA better communicate with partners and on which subjects?
-
- comment
-
-
-
-
-
- Odoo Feedback
-
- 20
-
- open
- 1
- 1
- 5
-
-
-
-
- Who are you?
-
-
-
-
-
- 1
- What is your company's name?
-
- single_textbox
-
-
-
-
- 1
- What is your company's sector?
-
- multiple_choice_multiple_ans
-
-
-
-
- 1
- Agriculture
-
-
-
-
- 1
- Bank & Finance
-
-
-
-
- 1
- Engineering
-
-
-
-
- 1
- Chemical & Pharmaceutical
-
-
-
-
- 1
- HR
-
-
-
-
- 1
- Construction
-
-
-
-
- 1
- Retail
-
-
-
-
- 1
- Electronics
-
-
-
-
- 1
- Energy
-
-
-
-
- 1
- Education
-
-
-
-
- 1
- Industry
-
-
-
-
- 1
- Logistics
-
-
-
-
- 1
- Media & Entertainment
-
-
-
-
- 1
- Public & Nonprofit
-
-
-
-
- 1
- Services
-
-
-
-
- 1
- Healthcare
-
-
-
-
- 1
- Telecommunication And ICT
-
-
-
-
- 1
- Tourism & Catering
-
-
-
-
- 1
- Other sector
-
-
-
-
- at least
-
- This question requires an answer.
-
-
-
- 1
- Which activities do you plan to manage with Odoo ?
-
- multiple_choice_multiple_ans
-
-
-
- 1
- Customer Relationship Management
-
-
-
-
- 1
- Accounting & Finance
-
-
-
-
- 1
- Inventory Management
-
-
-
-
- 1
- Manufacturing
-
-
-
-
- 1
- Human Resources
-
-
-
-
- 1
- Project Management
-
-
-
-
- 1
- Sales & Purchases
-
-
-
-
- 1
- Other
-
-
-
-
- at least
-
- This question requires an answer.
-
-
-
- 1
- How did you discover Odoo ?
-
- multiple_choice_multiple_ans
-
-
-
- 1
- OpenERP website
-
-
-
-
- 1
- Search Engine
-
-
-
-
- 1
- Word of mouth
-
-
-
-
- 1
- Trade show
-
-
-
-
- 1
- Press
-
-
-
-
- 1
- Other
-
-
-
-
- at least
-
- This question requires an answer.
-
-
-
- Subscription and configuration
-
-
-
-
-
- 1
- Why did you subscribe to Odoo?
-
- multiple_choice_only_one_ans
-
-
-
- 1
- I was already using OpenERP and wanted to switch to an online offer
-
-
-
-
- 1
- It's easier and cheaper than maintaining by myself
-
-
-
-
- 1
- I am looking for a SaaS offer for my customers
-
-
-
-
- 1
- After having tested it, I plan to download and install it by myself for later use
-
-
-
-
- 1
- After having tested it, I don't plan to use it
-
-
-
-
-
- 1
- How much time did you spend to configure the application?
-
- matrix_of_choices_only_one_ans
-
-
-
- 1
- Creating users and access rights
-
-
-
-
- 1
- Adding the modules I need
-
-
-
-
- 1
- Configuring the modules
-
-
-
-
- 1
- Importing my data
-
-
-
-
- 1
- Creating the initial data
-
-
-
-
- I didn't try
-
- 1
- 1
-
-
- A couple of weeks
-
- 1
- 1
-
-
- A couple of days
-
- 1
- 1
-
-
- A couple of hours
-
- 1
- 1
-
-
- A couple of minutes
-
- 1
- 1
-
-
-
- 1
- Do you plan to continue using Odoo?
-
- multiple_choice_only_one_ans
- text
- No...Why?
-
- True
-
-
- 1
- Yes
-
-
-
-
- 1
- No
-
-
-
-
-
-
-
-
- Using Odoo
-
-
-
-
- 1
- Which interface would you prefer to use?
-
- multiple_choice_only_one_ans
-
-
-
- 1
- The web interface
-
-
-
-
- 1
- The rich interface (GTK or KDE)
-
-
-
-
- 1
- Both
-
-
-
-
-
-
-
-
- 1
- Give your opinion :
-
- matrix_of_choices_only_one_ans
-
-
-
- 1
- Is Odoo Website appropriately structured?
-
-
-
-
- 1
- Are Odoo Website FAQ clear and concise?
-
-
-
-
- 1
- Is OpenERP Web Client simple and useful?
-
-
-
-
- 1
- Is the Control Center user-friendly?
-
-
-
-
- No Opinion
-
- 1
- 1
-
-
- Not at all
-
- 1
- 1
-
-
- Not enough
-
- 1
- 1
-
-
- Yes, but could be better
-
- 1
- 1
-
-
- Absolutely
-
- 1
- 1
-
-
- at least
-
- This question requires an answer.
-
-
-
- 1
- What do you think about ...
-
- matrix_of_choices_only_one_ans
- 1
-
-
-
- 1
- Migrating a database to a new version
-
-
-
-
- 1
- Browsing and downloading your backups
-
-
-
-
- 1
- Duplicating a database
-
-
-
-
- 1
- Checking your monthly hours statistics
-
-
-
-
- 1
- Creating a support ticket
-
-
-
-
- I didn't try
-
- 1
- 1
-
-
- Hard
-
- 1
- 1
-
-
- Difficult
-
- 1
- 1
-
-
- Easy
-
- 1
- 1
-
-
- Very Easy
-
- 1
- 1
-
-
- 1
- at least
-
- This question requires an answer.
-
-
-
- 1
- In your opinion, which modules are missing in Odoo? Give examples :
-
- single_textbox
- 1
-
-
-
-
-
- The offer
-
-
-
-
-
- 1
- How often would you prefer to receive your prepaid bill?
-
- multiple_choice_only_one_ans
-
-
-
- 1
- Monthly
-
-
-
-
- 1
- Annually with 20% discount
-
-
-
-
- 1
- Every 2 years with 25% discount
-
-
-
-
-
-
-
-
- 1
- Do you plan to use the document management system?
-
- multiple_choice_only_one_ans
- text
- Comment
-
- True
-
-
- 1
- Yes, I plan to use (GB)
-
-
-
-
- 1
- No
-
-
-
-
-
-
-
-
- 1
- How satisfied are you with Odoo's support services :
-
- matrix_of_choices_only_one_ans
-
-
-
- 1
- The time between your question and our answer is
-
-
-
-
- 1
- The pertinence of our answers is
-
-
-
-
- No Opinion
-
- 1
- 1
-
-
- Very Bad
-
- 1
- 1
-
-
- Bad
-
- 1
- 1
-
-
- Good
-
- 1
- 1
-
-
- Very Good
-
- 1
- 1
-
-
- at least
-
- This question requires an answer.
-
-
-
- 1
- Give your opinion about Odoo's
-
- matrix_of_choices_only_one_ans
-
-
-
-
- 1
- Pricing criteria
-
-
-
-
- 1
- Pricing understanding
-
-
-
-
- 1
- Range of available modules
-
-
-
-
- No Opinion
-
- 1
- 1
-
-
- Very Bad
-
- 1
- 1
-
-
- Bad
-
- 1
- 1
-
-
- Good
-
- 1
- 1
-
-
- Very Good
-
- 1
- 1
-
-
- at least
-
- This question requires an answer.
-
-
-
- 1
- If you have any additional comments, write them here :
-
- comment
-
-
-
-
-
-
-
-
- 4
- 20
-
- open
- 5
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
-
-
- 1
- 1
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
- Community Survey
- Please take a few minutes to complete this survey on the quality of service we provide. We welcome your feedback and appreciate your honesty. With your help, we hope to strengthen the bond between our clients.
-
- open
-
-
-
-
- 5
- 20
-
-
-
-
- Service Characteristics
-
-
-
-
-
-
- Performance Indicator
-
-
-
-
-
-
- Client Information
-
-
-
-
-
-
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
-
- This question requires an answer.
-
- Please rank, your criteria for choosing an organization.
- char
-
-
- matrix_of_choices_only_one_ans
-
- The comment you entered is in an invalid format.
-
-
-
- at least
- Other (please specify)
-
-
-
-
-
-
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
-
- This question requires an answer.
-
- Please rate the following questions.
- char
-
-
- matrix_of_choices_only_one_ans
-
- The comment you entered is in an invalid format.
-
-
-
- at least
- Other (please specify)
-
-
-
-
-
-
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
-
- This question requires an answer.
-
- How would you prefer for us to provide most communications?
- char
-
-
- multiple_choice_only_one_ans
-
- The comment you entered is in an invalid format.
-
-
-
- at least
- Other (please specify)
-
-
-
-
-
-
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
-
- This question requires an answer.
-
- What should we improve on (please be specific)?
- char
-
-
- comment
-
- The comment you entered is in an invalid format.
-
-
-
- at least
- Other (please specify)
-
-
-
-
-
-
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
-
- This question requires an answer.
-
- What do we do well?
- char
-
-
- comment
-
- The comment you entered is in an invalid format.
-
-
-
- at least
- Other (please specify)
-
-
-
-
-
-
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
-
- This question requires an answer.
-
- What are the most important challenges facing your organization this year?
- char
-
-
- comment
-
- The comment you entered is in an invalid format.
-
-
-
- at least
- Other (please specify)
-
-
-
-
-
-
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
-
- This question requires an answer.
-
- How can we help you do your job better?
- char
-
-
- comment
-
- The comment you entered is in an invalid format.
-
-
-
- at least
- Other (please specify)
-
-
-
-
-
-
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
-
- This question requires an answer.
-
- Please provide any additional comments.
- char
-
-
- comment
-
- The comment you entered is in an invalid format.
-
-
-
- at least
- Other (please specify)
-
-
-
-
-
-
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
-
- This question requires an answer.
-
- Contact information
- char
-
-
- multiple_textboxes_diff_type
-
- The comment you entered is in an invalid format.
-
-
-
- at least
- Other (please specify)
-
-
-
-
-
-
- do_not_validate
- do_not_validate
- Please enter a comment.
- The choices need to add up to [enter sum here].
-
- The comment you entered is in an invalid format.
-
-
- This question requires an answer.
-
- How many years have you been a client?
- char
-
-
- multiple_choice_only_one_ans
-
- The comment you entered is in an invalid format.
-
-
-
- at least
- Other (please specify)
-
-
-
-
-
-
-
- Most Important
-
-
-
-
-
-
-
- Very Important
-
-
-
-
-
-
-
- Important
-
-
-
-
-
-
-
- Less Important
-
-
-
-
-
-
-
- Not Important
-
-
-
-
-
-
-
- Excellent
-
-
-
-
-
-
-
- Above Average
-
-
-
-
-
-
-
- Average
-
-
-
-
-
-
-
- Below Average
-
-
-
-
-
-
-
- Poor
-
-
-
-
-
-
-
- N/A
-
-
-
-
-
-
-
- Email
-
- char
-
-
-
-
-
-
- The quality of our responses to your questions and concerns.
-
- char
-
-
-
-
-
-
- 0 - 2 years
-
- char
-
-
-
-
-
-
- Name
-
- char
-
-
-
-
-
-
- Industry/marketplace knowledge
-
- char
-
-
-
-
-
-
- Phone
-
- char
-
-
-
-
-
-
- 3 - 5 years
-
- char
-
-
-
-
-
-
- Length of time in business
-
- char
-
-
-
-
-
-
- The timeliness of our Representatives' response to your needs.
-
- char
-
-
-
-
-
-
- Company
-
- char
-
-
-
-
-
-
- The knowledge level of your Representative.
-
- char
-
-
-
-
-
-
- Mail
-
- char
-
-
-
-
-
-
- Phone number
-
- char
-
-
-
-
-
-
- Consultative capabilities
-
- char
-
-
-
-
-
-
- 6 - 10 years
-
- char
-
-
-
-
-
-
- 10 + years
-
- char
-
-
-
-
-
-
- Your Representative keeps you informed of changes.
-
- char
-
-
-
-
-
-
- Face-to-Face
-
- char
-
-
-
-
-
-
- Technology and Tools provided
-
- char
-
-
-
-
-
-
- Email address
-
- email
-
-
-
-
-
-
- Other
-
- char
-
-
-
-
-
-
- Personal Referral
-
- char
-
-
-
-
-
-
- How is our ability to anticipate your needs and provide assistance pro actively.
-
- char
-
-
-
-
-
-
- Lowest rate
-
- char
-
-
-
-
-
-
- Our products and services we provide meet your objectives.
-
- char
-
-
-
-
-
-
- Responsiveness to requests
-
- char
-
-
-
-
-
-
- We are easy to work with.
-
- char
-
-
-
-
-
-
- Value-added services
-
- char
-
-
-
-
-
-
- Overall, how do you rank our services to you.
-
- char
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- done
-
-
- link
-
-
-
-
-
- done
-
-
- link
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
- OpenERP SA
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- skip
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
- OpenERP SA
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
- survey
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- skip
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- done
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/survey/survey_report.xml b/addons/survey/survey_report.xml
deleted file mode 100644
index 647be4c26c5..00000000000
--- a/addons/survey/survey_report.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/survey/survey_view.xml b/addons/survey/survey_view.xml
deleted file mode 100644
index 2c43364871d..00000000000
--- a/addons/survey/survey_view.xml
+++ /dev/null
@@ -1,1258 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- survey_form
- survey
-
-
-
-
-
-
- survey_tree
- survey
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- survey_search
- survey
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- event.survey.kanban
- survey
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- survey_type_tree
- survey.type
-
-
-
-
-
-
-
-
-
- Survey Type
- survey.type
- form
- tree,form
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/survey/test/__init__.py b/addons/survey/test/__init__.py
new file mode 100644
index 00000000000..b2a1a5accf2
--- /dev/null
+++ b/addons/survey/test/__init__.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Business Applications
+# Copyright (c) 2012-TODAY OpenERP S.A.
+#
+# 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 .
+#
+##############################################################################
+
+
+from . import test_survey
+
+checks = [
+ test_survey
+]
diff --git a/addons/survey/test/draft2open2close_request.yml b/addons/survey/test/draft2open2close_request.yml
deleted file mode 100644
index 9d80952855b..00000000000
--- a/addons/survey/test/draft2open2close_request.yml
+++ /dev/null
@@ -1,50 +0,0 @@
--
- In order to check Survey Request of the survey "Initial Partner Feedback" I create a Survey Request for survey "Initial Partner Feedback".
--
- !record {model: survey.request, id: survey_request_1}:
- survey_id: survey_Initial_partner_feedback
- user_id: base.user_demo
--
- !assert {model: survey.request, id: survey_request_1, string: Survey Request should be in draft state}:
- - state == 'draft'
--
- I set Survey Request for the survey in waiting state.
--
- !python {model: survey.request}: |
- self.survey_req_waiting_answer(cr, uid, [ref("survey_request_1")], context)
--
- I check that state of Survey Request for the survey is waiting or not.
--
- !assert {model: survey.request, id: survey_request_1, severity: error, string: Survey Request should be in waiting state}:
- - state == 'waiting_answer'
--
- I cancel the Survey Request of the survey.
--
- !python {model: survey.request}: |
- self.survey_req_cancel(cr, uid, [ref("survey_request_1")], context)
--
- I check that state of Survey Request of the survey is cancel or not.
--
- !assert {model: survey.request, id: survey_request_1, severity: error, string: Survey Request should be in cancel state}:
- - state == 'cancel'
--
- I set Survey Request of the survey in draft state.
--
- !python {model: survey.request}: |
- self.survey_req_draft(cr, uid, [ref("survey_request_1")], context)
--
- I check that state of Survey request of the survey is draft or not.
--
- !assert {model: survey.request, id: survey_request_1, severity: error, string: Survey Request should be in draft state}:
- - state == 'draft'
--
- I set survey request of the survey in done state.
--
- !python {model: survey.request}: |
- self.survey_req_waiting_answer(cr, uid, [ref("survey_request_1")], context)
- self.survey_req_done(cr, uid, [ref("survey_request_1")], context)
--
- I check that state of Survey request of the survey is done or not.
--
- !assert {model: survey.request, id: survey_request_1, severity: error, string: Survey Request should be in done state}:
- - state == 'done'
diff --git a/addons/survey/test/draft2open2close_survey.yml b/addons/survey/test/draft2open2close_survey.yml
deleted file mode 100644
index 926810c1429..00000000000
--- a/addons/survey/test/draft2open2close_survey.yml
+++ /dev/null
@@ -1,111 +0,0 @@
--
- In order to check the survey module in OpenERP I use the survey "Initial Partner Feedback".
--
- I set the survey in Open state.
--
- !python {model: survey}: |
- sur = self.survey_open(cr, uid, [ref("survey_Initial_partner_feedback")], context)
--
- I check state of survey is open or not.
--
- !assert {model: survey, id: survey_Initial_partner_feedback, severity: error, string: Survey should be in open state}:
- - state == 'open'
--
- I check that the survey is reopened or not.
--
- !python {model: survey}: |
- self.survey_cancel(cr, uid, [ref('survey_Initial_partner_feedback')],context)
- self.survey_open(cr, uid, [ref('survey_Initial_partner_feedback')],context)
--
- I check that state of survey is open or not.
--
- !assert {model: survey, id: survey_Initial_partner_feedback, severity: error, string: Survey should be in open state}:
- - state == 'open'
--
- I set the state of the survey open.
--
- !python {model: survey}: |
- sur = self.survey_open(cr, uid, [ref("survey_Initial_partner_feedback")], context)
--
- In order to print the survey I click on Print.
--
- !python {model: survey.print}: |
- id = self.create(cr, uid, {'survey_ids': [(6,0,[ref('survey.survey_Initial_partner_feedback')])]})
- self.action_next(cr, uid, [id], context)
--
- In order to answer the survey I click on "Answer a Survey" wizard.
--
- !python {model: survey.name.wiz}: |
- id = self.create(cr, uid, {'survey_id': ref("survey_Initial_partner_feedback")})
- self.action_next(cr, uid, [id], context)
--
- I give the answer of the first and second page of the survey.
--
- !python {model: survey.question.wiz}: |
- ctx = {'active_model':'survey', 'active_id': ref('survey_Initial_partner_feedback'), 'active_ids': [ref('survey_Initial_partner_feedback')]}
- self.fields_view_get(cr, uid, ref("survey.view_survey_question_message"),"form", context=ctx)
- values = self.default_get(cr, uid, ['name'], ctx)
- id = self.create(cr, uid, {str(ref("survey_initial_question_company_name")) +"_single" :'Tiny' , str(ref("survey_initial_question_company_size")) + "_selection" : int(ref("survey.survey_initial_question_company_size_51")), }, context)
- self.action_next(cr, uid, [id], context)
- id = self.create(cr, uid, {str(ref("survey_initial_question_contract_customers")) + "_selection" : int(ref("survey_initial_answer_sometimes")), str(ref("survey_initial_question_sell_to_your_customers")) + "_selection" : int(ref("survey_initial_answer_maintenance_contract")), }, context)
- self.action_next(cr, uid, [id], context)
--
- I print the answers of the survey.
--
- !python {model: survey.browse.answer}: |
- id = self.create(cr, uid, {'survey_id': ref('survey.survey_Initial_partner_feedback')})
- self.action_next(cr, uid, [id], context)
--
- I edit questions of the survey as per requirement.
--
- !python {model: survey.question.wiz}: |
- name_wiz_obj = self.pool.get('survey.name.wiz')
- id = name_wiz_obj.create(cr, uid, {'survey_id': ref("survey_Initial_partner_feedback")})
- ctx = {'active_model':'survey', 'active_id': ref('survey_Initial_partner_feedback'), 'active_ids': [ref('survey_Initial_partner_feedback')], 'question_id': ref('survey_initial_question_company_name'), 'page_number': -1,'sur_name_id': id}
- self.action_edit_question(cr, uid, [ref('survey_initial_question_company_name')], context = ctx)
- self.action_delete_question(cr, uid, [ref('survey_initial_question_company_name')], context = ctx)
- self.action_new_question(cr, uid, [], context = ctx)
--
- I edit Page of the survey as per requirement.
--
- !python {model: survey.question.wiz}: |
- name_wiz_obj = self.pool.get('survey.name.wiz')
- id = name_wiz_obj.create(cr, uid, {'survey_id': ref("survey_Initial_partner_feedback")})
- ctx = {'active_model':'survey', 'active_id': ref('survey_Initial_partner_feedback'), 'active_ids': [ref('survey_Initial_partner_feedback')], 'page_id': ref('survey_initial_page_Contracts'), 'sur_name_id': id}
- self.action_edit_page(cr, uid, [ref('survey_initial_page_Contracts')], context = ctx)
- self.action_delete_page(cr, uid, [ref('survey_initial_page_Contracts')], context = ctx)
- self.action_new_page(cr, uid, [], context = ctx)
--
- In order to send invitation to the users I click on "Send Invitation" wizard.
--
- !python {model: survey.send.invitation}: |
- context = {'active_model':'survey', 'active_id': ref('survey_Initial_partner_feedback'), 'active_ids': [ref('survey_Initial_partner_feedback')]}
- values = self.default_get(cr, uid, ['mail_from', 'mail_subject', 'send_mail_existing', 'mail_subject_existing', 'mail', 'partner_ids', 'send_mail'], context)
- values['mail_from'] = 'Surveyor'
- new_id = self.create(cr, uid, values)
- self.action_send(cr, uid, [new_id], context)
--
- I set the value in "Total start survey" field.
--
- !record {model: survey, id: survey_Initial_partner_feedback}:
- tot_start_survey: 1
--
- I set the survey in Cancel state.
--
- !python {model: survey}: |
- self.survey_cancel(cr, uid, [ref("survey_Initial_partner_feedback")], context)
--
- I check state of survey is cancel or not.
--
- !assert {model: survey, id: survey_Initial_partner_feedback, severity: error, string: Survey should be in cancel state}:
- - state == 'cancel'
--
- I set the survey in close state.
--
- !python {model: survey}: |
- self.survey_close(cr, uid, [ref("survey_Initial_partner_feedback")], context)
--
- I check state of Survey is close or not.
--
- !assert {model: survey, id: survey_Initial_partner_feedback, severity: error, string: Survey should be in close state}:
- - state == 'close'
diff --git a/addons/survey/test/survey_question_type.yml b/addons/survey/test/survey_question_type.yml
deleted file mode 100644
index e03d7710ea0..00000000000
--- a/addons/survey/test/survey_question_type.yml
+++ /dev/null
@@ -1,6 +0,0 @@
--
- I check the question type of the survey "Initial Partner Feedback".
--
- !python {model: survey.question}: |
- sur_question = self.on_change_type(cr, uid, [ref("survey_Initial_partner_feedback")], 'multiple_textboxes_diff_type')
- assert sur_question
diff --git a/addons/survey/test/survey_report.yml b/addons/survey/test/survey_report.yml
deleted file mode 100644
index 36eff699075..00000000000
--- a/addons/survey/test/survey_report.yml
+++ /dev/null
@@ -1,26 +0,0 @@
--
- I print the Survey Browse Response Report through the wizard.
--
- !python {model: survey}: |
- ctx = {'model': 'survey','active_ids': [(6,0,[ref('survey_partner_feedback')])]}
- data_dict = {'response_ids' : [(6,0,[ref('survey.survey_partner_feedback')])], 'page_number' : True, 'without_pagebreak': True}
- from openerp.tools import test_reports
- test_reports.try_report_action(cr, uid, 'action_view_survey_print_answer',wiz_data=data_dict, context=ctx, our_module='survey')
-
--
- I print the Survey Analysis Report through the wizard.
--
- !python {model: survey}: |
- ctx = {'model': 'survey','active_ids': [(6,0,[ref('survey_partner_feedback')])]}
- data_dict = {'survey_ids' : [(6,0,[ref('survey.survey_partner_feedback')])]}
- from openerp.tools import test_reports
- test_reports.try_report_action(cr, uid, 'action_view_survey_print_statistics',wiz_data=data_dict, context=ctx, our_module='survey')
-
--
- I print the Survey Form Report through the wizard.
--
- !python {model: survey}: |
- ctx = {'model': 'survey','active_ids': [(6,0,[ref('survey_partner_feedback')])]}
- data_dict = {'survey_ids' : [(6,0,[ref('survey.survey_partner_feedback')])], 'page_number' : True, 'without_pagebreak': True}
- from openerp.tools import test_reports
- test_reports.try_report_action(cr, uid, 'action_view_survey_print',wiz_data=data_dict, context=ctx, our_module='survey')
diff --git a/addons/survey/test/test_survey.py b/addons/survey/test/test_survey.py
new file mode 100644
index 00000000000..c3a3f4459af
--- /dev/null
+++ b/addons/survey/test/test_survey.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Business Applications
+# Copyright (c) 2014-TODAY OpenERP S.A.
+#
+# 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 .
+#
+##############################################################################
+
+from openerp.tests import common
+
+
+class test_survey(common.TransactionCase):
+
+ def setUp(self):
+ super(test_survey, self).setUp()
+ cr, uid, context = self.cr, self.uid, {}
+ pass
+
+ def test_00_create_survey_and_questions(self):
+ cr, uid, context = self.cr, self.uid, {}
+ pass
+
+ def test_01_fill_survey(self):
+ pass
+
+ def test_02_answer_survey(self):
+ pass
diff --git a/addons/survey/views/survey_result.xml b/addons/survey/views/survey_result.xml
new file mode 100644
index 00000000000..40a8a75fc28
--- /dev/null
+++ b/addons/survey/views/survey_result.xml
@@ -0,0 +1,316 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Filters Clear All Filters
+
+
+ All surveysFinished surveys
+
+
+ All surveysFinished surveys
+
+
+
+
+
You can create surveys for different purposes: customer opinion, services feedback, recruitment interviews, employee's periodical evaluations, marketing campaigns, etc.
+
Design easily your survey, send invitations to answer by email and analyse answers.
+
+
+
+
+
+
+
+ Form view for survey page
+ survey.page
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/survey/wizard/__init__.py b/addons/survey/wizard/__init__.py
index 0ea0e5cd424..d4090570b93 100644
--- a/addons/survey/wizard/__init__.py
+++ b/addons/survey/wizard/__init__.py
@@ -19,12 +19,4 @@
#
##############################################################################
-import survey_send_invitation
-import survey_print_statistics
-import survey_print_answer
-import survey_browse_answer
-import survey_selection
-import survey_answer
-import survey_print
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+import survey_email_compose_message
diff --git a/addons/survey/wizard/survey_answer.py b/addons/survey/wizard/survey_answer.py
deleted file mode 100644
index 5b9bbb5de7e..00000000000
--- a/addons/survey/wizard/survey_answer.py
+++ /dev/null
@@ -1,1259 +0,0 @@
-## -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL ().
-#
-# 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 .
-#
-##############################################################################
-
-import base64
-import datetime
-from lxml import etree
-import os
-from time import strftime
-
-from openerp import tools
-from openerp.modules.module import get_module_resource
-from openerp.osv import fields, osv
-import openerp.report
-from openerp.tools import to_xml
-from openerp.tools.translate import _
-from openerp.tools.safe_eval import safe_eval
-
-class survey_question_wiz(osv.osv_memory):
- _name = 'survey.question.wiz'
- _columns = {
- 'name': fields.integer('Number'),
- }
-
- def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
- """
- Fields View Get method :- generate the new view and display the survey pages of selected survey.
- """
- if context is None:
- context = {}
- result = super(survey_question_wiz, self).fields_view_get(cr, uid, view_id, \
- view_type, context, toolbar,submenu)
-
- surv_name_wiz = self.pool.get('survey.name.wiz')
- survey_obj = self.pool.get('survey')
- page_obj = self.pool.get('survey.page')
- que_obj = self.pool.get('survey.question')
- ans_obj = self.pool.get('survey.answer')
- sur_response_obj = self.pool.get('survey.response')
- que_col_head = self.pool.get('survey.question.column.heading')
- user_obj = self.pool.get('res.users')
- mail_message = self.pool.get('mail.message')
-
- if view_type in ['form']:
- wiz_id = 0
- sur_name_rec = None
- if 'sur_name_id' in context:
- sur_name_rec = surv_name_wiz.browse(cr, uid, context['sur_name_id'], context=context)
- elif 'survey_id' in context:
- res_data = {
- 'survey_id': context.get('survey_id', False),
- 'page_no': -1,
- 'page': 'next',
- 'transfer': 1,
- 'response': 0
- }
- wiz_id = surv_name_wiz.create(cr, uid, res_data)
- sur_name_rec = surv_name_wiz.browse(cr, uid, wiz_id, context=context)
- context.update({'sur_name_id' :wiz_id})
-
- if context.has_key('active_id'):
- context.pop('active_id')
-
- survey_id = context.get('survey_id', False)
- if not survey_id:
- # Try one more time to find it
- if sur_name_rec and sur_name_rec.survey_id:
- survey_id = sur_name_rec.survey_id.id
- else:
- # raise osv.except_osv(_('Error!'), _("Cannot locate survey for the question wizard!"))
- # If this function is called without a survey_id in
- # its context, it makes no sense to return any view.
- # Just return the default, empty view for this object,
- # in order to please random calls to this fn().
- return super(survey_question_wiz, self).\
- fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context,
- toolbar=toolbar, submenu=submenu)
- sur_rec = survey_obj.browse(cr, uid, survey_id, context=context)
- p_id = map(lambda x:x.id, sur_rec.page_ids)
- total_pages = len(p_id)
- pre_button = False
- readonly = 0
-
- if context.get('response_id', False) \
- and int(context['response_id'][0]) > 0:
- readonly = 1
-
- if not sur_name_rec.page_no + 1 :
- surv_name_wiz.write(cr, uid, [context['sur_name_id'],], {'store_ans':{}})
-
- sur_name_read = surv_name_wiz.browse(cr, uid, context['sur_name_id'], context=context)
- page_number = int(sur_name_rec.page_no)
- if sur_name_read.transfer or not sur_name_rec.page_no + 1:
- surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':False})
- flag = False
- fields = {}
- if sur_name_read.page == "next" or sur_name_rec.page_no == -1:
- if total_pages > sur_name_rec.page_no + 1:
- if ((context.has_key('active') and not context.get('active', False)) \
- or not context.has_key('active')) and not sur_name_rec.page_no + 1:
- if sur_rec.state != "open" :
- raise osv.except_osv(_('Warning!'),_("You cannot answer because the survey is not open."))
- cr.execute('select count(id) from survey_history where user_id=%s\
- and survey_id=%s', (uid,survey_id))
- res = cr.fetchone()[0]
- user_limit = survey_obj.browse(cr, uid, survey_id)
- user_limit = user_limit.response_user
- if user_limit and res >= user_limit:
- raise osv.except_osv(_('Warning!'),_("You cannot answer this survey more than %s times.") % (user_limit))
-
- if sur_rec.max_response_limit and sur_rec.max_response_limit <= sur_rec.tot_start_survey and not sur_name_rec.page_no + 1:
- survey_obj.write(cr, uid, survey_id, {'state':'close', 'date_close':strftime("%Y-%m-%d %H:%M:%S")})
-
- p_id = p_id[sur_name_rec.page_no + 1]
- surv_name_wiz.write(cr, uid, [context['sur_name_id'],], {'page_no' : sur_name_rec.page_no + 1})
- flag = True
- page_number += 1
- if sur_name_rec.page_no > - 1:
- pre_button = True
- else:
- flag = True
- else:
- if sur_name_rec.page_no != 0:
- p_id = p_id[sur_name_rec.page_no - 1]
- surv_name_wiz.write(cr, uid, [context['sur_name_id'],],\
- {'page_no' : sur_name_rec.page_no - 1})
- flag = True
- page_number -= 1
-
- if sur_name_rec.page_no > 1:
- pre_button = True
- if flag:
- pag_rec = page_obj.browse(cr, uid, p_id, context=context)
- note = False
- question_ids = []
- if pag_rec:
- title = pag_rec.title
- note = pag_rec.note
- question_ids = pag_rec.question_ids
- else:
- title = sur_rec.title
- xml_form = etree.Element('form', {'string': tools.ustr(title)})
- if context.has_key('active') and context.get('active',False) and context.has_key('edit'):
- context.update({'page_id' : tools.ustr(p_id),'page_number' : sur_name_rec.page_no , 'transfer' : sur_name_read.transfer})
- xml_group3 = etree.SubElement(xml_form, 'group', {'col': '4', 'colspan': '4'})
- etree.SubElement(xml_group3, 'button', {'string' :'Add Page','icon': "gtk-new", 'type' :'object','name':"action_new_page", 'context' : tools.ustr(context)})
- etree.SubElement(xml_group3, 'button', {'string' :'Edit Page','icon': "gtk-edit", 'type' :'object','name':"action_edit_page", 'context' : tools.ustr(context)})
- etree.SubElement(xml_group3, 'button', {'string' :'Delete Page','icon': "gtk-delete", 'type' :'object','name':"action_delete_page", 'context' : tools.ustr(context)})
- etree.SubElement(xml_group3, 'button', {'string' :'Add Question','icon': "gtk-new", 'type' :'object','name':"action_new_question", 'context' : tools.ustr(context)})
-
- # FP Note
- xml_group = xml_form
-
- if context.has_key('response_id') and context.get('response_id', False) \
- and int(context.get('response_id',0)[0]) > 0:
- # TODO: l10n, cleanup this code to make it readable. Or template?
- xml_group = etree.SubElement(xml_form, 'group', {'col': '40', 'colspan': '4'})
- record = sur_response_obj.browse(cr, uid, context['response_id'][context['response_no']])
- etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(_('Answer Of :- ') + record.user_id.name + _(', Date :- ') + record.date_create.split('.')[0] )), 'align':"0.0"})
- etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(_(" Answer :- ") + str(context.get('response_no',0) + 1) +"/" + str(len(context.get('response_id',0))) )), 'align':"0.0"})
- if context.get('response_no',0) > 0:
- etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_forward_previous",'string': tools.ustr("Previous Answer"),'type':"object"})
- if context.get('response_no',0) + 1 < len(context.get('response_id',0)):
- etree.SubElement(xml_group, 'button', {'colspan':"1",'icon': "gtk-go-forward", 'name':"action_forward_next",'string': tools.ustr("Next Answer") ,'type':"object",'context' : tools.ustr(context)})
-
- if wiz_id:
- fields["wizardid_" + str(wiz_id)] = {'type':'char', 'size' : 255, 'string':"", 'views':{}}
- etree.SubElement(xml_form, 'field', {'invisible':'1','name': "wizardid_" + str(wiz_id),'default':str(lambda *a: 0),'modifiers':'{"invisible":true}'})
-
- if note:
- xml_group_note = etree.SubElement(xml_form, 'group', {'col': '1','colspan': '4'})
- for que_test in note.split('\n'):
- etree.SubElement(xml_group_note, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
- que_ids = question_ids
- qu_no = 0
-
- for que in que_ids:
- qu_no += 1
- que_rec = que_obj.browse(cr, uid, que.id, context=context)
- descriptive_text = ""
- separator_string = tools.ustr(qu_no) + "." + tools.ustr(que_rec.question)
- if ((context.has_key('active') and not context.get('active',False)) or not context.has_key('active')) and que_rec.is_require_answer:
- star = '*'
- else:
- star = ''
- if context.has_key('active') and context.get('active',False) and \
- context.has_key('edit'):
- etree.SubElement(xml_form, 'separator', {'string': star+to_xml(separator_string)})
-
- xml_group1 = etree.SubElement(xml_form, 'group', {'col': '2', 'colspan': '2'})
- context.update({'question_id' : tools.ustr(que.id),'page_number': sur_name_rec.page_no , 'transfer' : sur_name_read.transfer, 'page_id' : p_id})
- etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-edit", 'type' :'object', 'name':"action_edit_question", 'context' : tools.ustr(context)})
- etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-delete", 'type' :'object','name':"action_delete_question", 'context' : tools.ustr(context)})
- else:
- etree.SubElement(xml_form, 'newline')
- etree.SubElement(xml_form, 'separator', {'string': star+to_xml(separator_string)})
-
- ans_ids = que_rec.answer_choice_ids
- xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
-
- if que_rec.type == 'multiple_choice_only_one_ans':
- selection = []
- for ans in ans_ids:
- selection.append((tools.ustr(ans.id), ans.answer))
- xml_group = etree.SubElement(xml_group, 'group', {'col': '2', 'colspan': '2'})
- etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_selection"})
- fields[tools.ustr(que.id) + "_selection"] = {'type':'selection', 'selection' :selection, 'string':_('Answer')}
-
- elif que_rec.type == 'multiple_choice_multiple_ans':
- xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
- for ans in ans_ids:
- etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
- fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'boolean', 'string':ans.answer}
-
- elif que_rec.type in ['matrix_of_choices_only_one_ans', 'rating_scale']:
- if que_rec.comment_column:
- col = "4"
- colspan = "4"
- else:
- col = "2"
- colspan = "2"
- xml_group = etree.SubElement(xml_group, 'group', {'col': tools.ustr(col), 'colspan': tools.ustr(colspan)})
- for row in ans_ids:
- etree.SubElement(xml_group, 'newline')
- etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'name': tools.ustr(que.id) + "_selection_" + tools.ustr(row.id),'string':to_xml(tools.ustr(row.answer))})
- selection = [('','')]
- for col in que_rec.column_heading_ids:
- selection.append((str(col.id), col.title))
- fields[tools.ustr(que.id) + "_selection_" + tools.ustr(row.id)] = {'type':'selection', 'selection' : selection, 'string': "Answer"}
- if que_rec.comment_column:
- fields[tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id) + "_field"] = {'type':'char', 'size' : 255, 'string':tools.ustr(que_rec.column_name), 'views':{}}
- etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id)+ "_field"})
-
- elif que_rec.type == 'matrix_of_choices_only_multi_ans':
- xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
- etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
- for col in que_rec.column_heading_ids:
- etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
- for row in ans_ids:
- etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer)) +' :-', 'align': '0.0'})
- for col in que_col_head.browse(cr, uid, [head.id for head in que_rec.column_heading_ids]):
- etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id), 'nolabel':"1"})
- fields[tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id)] = {'type':'boolean', 'string': col.title}
-
- elif que_rec.type == 'matrix_of_drop_down_menus':
- xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
- etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
- for col in que_rec.column_heading_ids:
- etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
- for row in ans_ids:
- etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer))+' :-', 'align': '0.0'})
- for col in que_rec.column_heading_ids:
- selection = []
- if col.menu_choice:
- for item in col.menu_choice.split('\n'):
- if item and not item.strip() == '': selection.append((item ,item))
- etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id),'nolabel':'1'})
- fields[tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id)] = {'type':'selection', 'string': col.title, 'selection':selection}
-
- elif que_rec.type == 'multiple_textboxes':
- xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
- type = "char"
- if que_rec.is_validation_require:
- if que_rec.validation_type in ['must_be_whole_number']:
- type = "integer"
- elif que_rec.validation_type in ['must_be_decimal_number']:
- type = "float"
- elif que_rec.validation_type in ['must_be_date']:
- type = "date"
- for ans in ans_ids:
- etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
- if type == "char" :
- fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
- else:
- fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(type), 'string':ans.answer}
-
- elif que_rec.type == 'numerical_textboxes':
- xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
- for ans in ans_ids:
- etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"})
- fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"] = {'type':'integer', 'string':ans.answer}
-
- elif que_rec.type == 'date':
- xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
- for ans in ans_ids:
- etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
- fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'date', 'string':ans.answer}
-
- elif que_rec.type == 'date_and_time':
- xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
- for ans in ans_ids:
- etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
- fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'datetime', 'string':ans.answer}
-
- elif que_rec.type == 'descriptive_text':
- if que_rec.descriptive_text:
- for que_test in que_rec.descriptive_text.split('\n'):
- etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
-
- elif que_rec.type == 'single_textbox':
- etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_single", 'nolabel':"1" ,'colspan':"4"})
- fields[tools.ustr(que.id) + "_single"] = {'type':'char', 'size': 255, 'string':"single_textbox", 'views':{}}
-
- elif que_rec.type == 'comment':
- etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_comment", 'nolabel':"1" ,'colspan':"4"})
- fields[tools.ustr(que.id) + "_comment"] = {'type':'text', 'string':"Comment/Eassy Box", 'views':{}}
-
- elif que_rec.type == 'table':
- xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids)), 'colspan': '4'})
- for col in que_rec.column_heading_ids:
- etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
- for row in range(0,que_rec.no_of_rows):
- for col in que_rec.column_heading_ids:
- etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_table_" + tools.ustr(col.id) +"_"+ tools.ustr(row), 'nolabel':"1"})
- fields[tools.ustr(que.id) + "_table_" + tools.ustr(col.id) +"_"+ tools.ustr(row)] = {'type':'char','size':255,'views':{}}
-
- elif que_rec.type == 'multiple_textboxes_diff_type':
- xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
- for ans in ans_ids:
- if ans.type == "email" :
- fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
- etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'widget':'email','width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
- else:
- etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
- if ans.type == "char" :
- fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
- elif ans.type in ['integer','float','date','datetime']:
- fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(ans.type), 'string':ans.answer}
- else:
- selection = []
- if ans.menu_choice:
- for item in ans.menu_choice.split('\n'):
- if item and not item.strip() == '': selection.append((item ,item))
- fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'selection', 'selection' : selection, 'string':ans.answer}
-
- if que_rec.type in ['multiple_choice_only_one_ans', 'multiple_choice_multiple_ans', 'matrix_of_choices_only_one_ans', 'matrix_of_choices_only_multi_ans', 'matrix_of_drop_down_menus', 'rating_scale'] and que_rec.is_comment_require:
- if que_rec.type in ['multiple_choice_only_one_ans', 'multiple_choice_multiple_ans'] and que_rec.comment_field_type in ['char','text'] and que_rec.make_comment_field:
- etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_otherfield", 'colspan':"4"})
- fields[tools.ustr(que.id) + "_otherfield"] = {'type':'boolean', 'string':que_rec.comment_label, 'views':{}}
- if que_rec.comment_field_type == 'char':
- etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
- fields[tools.ustr(que.id) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
- elif que_rec.comment_field_type == 'text':
- etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
- fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
- else:
- if que_rec.comment_field_type == 'char':
- etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
- etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
- fields[tools.ustr(que.id) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
- elif que_rec.comment_field_type == 'text':
- etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
- etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
- fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
-
- xml_footer = etree.SubElement(xml_form, 'footer', {'col': '8', 'colspan': '1', 'width':"100%"})
-
- if pre_button:
- etree.SubElement(xml_footer, 'label', {'string': ""})
- etree.SubElement(xml_footer, 'button', {'name':"action_previous",'string':_('Previous'),'type':"object"})
- but_string = _('Next')
- if int(page_number) + 1 == total_pages:
- but_string = _('Done')
- if context.has_key('active') and context.get('active',False) and int(page_number) + 1 == total_pages and context.has_key('response_id') and context.has_key('response_no') and context.get('response_no',0) + 1 == len(context.get('response_id',0)):
- etree.SubElement(xml_footer, 'label', {'string': ""})
- etree.SubElement(xml_footer, 'button', {'special' : 'cancel','string': tools.ustr("Done") ,'context' : tools.ustr(context), 'class':"oe_highlight"})
- elif context.has_key('active') and context.get('active', False) and int(page_number) + 1 == total_pages and context.has_key('response_id'):
- etree.SubElement(xml_footer, 'label', {'string': ""})
- etree.SubElement(xml_footer, 'button', {'name':"action_forward_next",'string': tools.ustr("Next Answer") ,'type':"object",'context' : tools.ustr(context), 'class':"oe_highlight"})
- elif context.has_key('active') and context.get('active',False) and int(page_number) + 1 == total_pages:
- etree.SubElement(xml_footer, 'label', {'string': ""})
- etree.SubElement(xml_footer, 'button', {'special': "cancel", 'string' : 'Done', 'context' : tools.ustr(context), 'class':"oe_highlight"})
- else:
- etree.SubElement(xml_footer, 'label', {'string': ""})
- etree.SubElement(xml_footer, 'button', {'name':"action_next",'string': tools.ustr(but_string) ,'type':"object",'context' : tools.ustr(context), 'class':"oe_highlight"})
- etree.SubElement(xml_footer, 'label', {'string': _('or')})
- etree.SubElement(xml_footer, 'button', {'special': "cancel",'string':_('Exit'),'class':"oe_link"})
- etree.SubElement(xml_footer, 'label', {'string': tools.ustr(page_number+ 1) + "/" + tools.ustr(total_pages), 'class':"oe_survey_title_page oe_right"})
-
- root = xml_form.getroottree()
- result['arch'] = etree.tostring(root)
- result['fields'] = fields
- result['context'] = context
- else:
- survey_obj.write(cr, uid, survey_id, {'tot_comp_survey' : sur_rec.tot_comp_survey + 1})
- sur_response_obj.write(cr, uid, [sur_name_read.response], {'state' : 'done'})
-
- # mark the survey request as done; call 'survey_req_done' on its actual model
- if context.get('active_model') in self.pool:
- survey_req_obj = self.pool[context.get('active_model')]
- if hasattr(survey_req_obj, 'survey_req_done'):
- survey_req_obj.survey_req_done(cr, uid, context.get('active_ids', []), context=context)
-
- if sur_rec.send_response:
- survey_data = survey_obj.browse(cr, uid, survey_id)
- response_id = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))['response']
- report = self.create_report(cr, uid, [survey_id], 'report.survey.browse.response', survey_data.title,context)
- attachments = {}
- pdf_filename = get_module_resource('survey', 'report') + survey_data.title + ".pdf"
- if os.path.exists(pdf_filename):
- file = open(pdf_filename)
- file_data = ""
- while 1:
- line = file.readline()
- file_data += line
- if not line:
- break
-
- attachments[survey_data.title + ".pdf"] = file_data
- file.close()
- os.remove(get_module_resource('survey', 'report') + survey_data.title + ".pdf")
- context.update({'response_id':response_id})
- user_email = user_obj.browse(cr, uid, uid, context).email
- resp_email = survey_data.responsible_id and survey_data.responsible_id.email or False
-
- if user_email and resp_email:
- user_name = user_obj.browse(cr, uid, uid, context=context).name
- mail = "Hello " + survey_data.responsible_id.name + ",\n\n " + str(user_name) + " has given the Response Of " + survey_data.title + " Survey.\nThe Response has been attached herewith.\n\n Thanks."
- vals = {'state': 'outgoing',
- 'subject': "Survey Answer Of " + user_name,
- 'body_html': '
%s
' % mail,
- 'email_to': [resp_email],
- 'email_from': user_email}
- if attachments:
- vals['attachment_ids'] = [(0,0,{'name': a_name,
- 'datas_fname': a_name,
- 'datas': str(a_content).encode('base64')})
- for a_name, a_content in attachments.items()]
- self.pool.get('mail.mail').create(cr, uid, vals, context=context)
-
- xml_form = etree.Element('form', {'string': _('Complete Survey Answer')})
- xml_footer = etree.SubElement(xml_form, 'footer', {'col': '6', 'colspan': '4' ,'class': 'oe_survey_title_height'})
-
- etree.SubElement(xml_form, 'separator', {'string': 'Survey Completed', 'colspan': "4"})
- etree.SubElement(xml_form, 'label', {'string': 'Thanks for your Answer'})
- etree.SubElement(xml_form, 'newline')
- etree.SubElement(xml_footer, 'button', {'special':"cancel",'string':"OK",'colspan':"2",'class':'oe_highlight'})
- root = xml_form.getroottree()
- result['arch'] = etree.tostring(root)
- result['fields'] = {}
- result['context'] = context
- return result
-
- def create_report(self, cr, uid, res_ids, report_name=False, file_name=False, context=None):
- """
- If any user give answer of survey then last create report of this answer and if 'E-mail Notification on Answer' set True in survey then send mail on responsible person of this survey and attach survey answer report in pdf format.
- """
- if not report_name or not res_ids:
- return (False, Exception('Report name and Resources ids are required !!!'))
- try:
- uid = 1
- result, format = openerp.report.render_report(cr, uid, res_ids, report_name[len('report.'):], {}, context)
- ret_file_name = get_module_resource('survey', 'report') + file_name + '.pdf'
- fp = open(ret_file_name, 'wb+');
- fp.write(result);
- fp.close();
-
- # hr.applicant: if survey answered directly in system: attach report to applicant
- if context.get('active_model') == 'hr.applicant':
- self.pool.get('hr.applicant').write(cr,uid,[context.get('active_ids')[0]],{'response':context.get('response_id')})
- result = base64.b64encode(result)
- file_name = file_name + '.pdf'
- ir_attachment = self.pool.get('ir.attachment').create(cr, uid,
- {'name': file_name,
- 'datas': result,
- 'datas_fname': file_name,
- 'res_model': context.get('active_model'),
- 'res_id': context.get('active_ids')[0]},
- context=context)
-
- except Exception,e:
- return (False, str(e))
- return (True, ret_file_name)
-
- def default_get(self, cr, uid, fields_list, context=None):
- """
- Assign Default value in particular field. If Browse Answers wizard run then read the value into database and Assigne to a particular fields.
- """
- value = {}
- if context is None:
- context = {}
- for field in fields_list:
- if field.split('_')[0] == 'progress':
- tot_page_id = self.pool.get('survey').browse(cr, uid, context.get('survey_id',False))
- tot_per = (float(100) * (int(field.split('_')[2]) + 1) / len(tot_page_id.page_ids))
- value[field] = tot_per
- response_obj = self.pool.get('survey.response')
- surv_name_wiz = self.pool.get('survey.name.wiz')
- if context.has_key('response_id') and context.get('response_id') and int(context['response_id'][0]) > 0:
- data = super(survey_question_wiz, self).default_get(cr, uid, fields_list, context)
- response_ans = response_obj.browse(cr, uid, context['response_id'][context['response_no']])
- fields_list.sort()
-
- for que in response_ans.question_ids:
- for field in fields_list:
- if field.split('_')[0] != "progress" and field.split('_')[0] == str(que.question_id.id):
- if que.response_answer_ids and len(field.split('_')) == 4 and field.split('_')[1] == "commentcolumn" and field.split('_')[3] == "field":
- for ans in que.response_answer_ids:
- if str(field.split('_')[2]) == str(ans.answer_id.id):
- value[field] = ans.comment_field
-
- if que.response_table_ids and len(field.split('_')) == 4 and field.split('_')[1] == "table":
- for ans in que.response_table_ids:
- if str(field.split('_')[2]) == str(ans.column_id.id) and str(field.split('_')[3]) == str(ans.name):
- value[field] = ans.value
-
- if que.comment and (field.split('_')[1] == "comment" or field.split('_')[1] == "other"):
- value[field] = tools.ustr(que.comment)
-
- elif que.single_text and field.split('_')[1] == "single":
- value[field] = tools.ustr(que.single_text)
-
- elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[1] == "selection":
- for ans in que.response_answer_ids:
- if str(field.split('_')[2]) == str( ans.answer_id.id):
- value[field] = str(ans.column_id.id)
-
- elif que.response_answer_ids and len(field.split('_')) == 2 and field.split('_')[1] == "selection":
- value[field] = str(que.response_answer_ids[0].answer_id.id)
-
- elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[2] != "multi" and field.split('_')[2] != "numeric":
- for ans in que.response_answer_ids:
- if str(field.split('_')[1]) == str( ans.answer_id.id) and str(field.split('_')[2]) == str(ans.column_id.id):
- if ans.value_choice:
- value[field] = ans.value_choice
- else:
- value[field] = True
-
- else:
- for ans in que.response_answer_ids:
- if str(field.split('_')[1]) == str( ans.answer_id.id):
- value[field] = ans.answer
-
- else:
-
- if not context.has_key('sur_name_id'):
- return value
- if context.has_key('active') and context.get('active',False):
- return value
- sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))
- ans_list = []
-
- for key,val in safe_eval(sur_name_read.get('store_ans',"{}")).items():
- for field in fields_list:
- if field in list(val):
- value[field] = val[field]
- return value
-
- def create(self, cr, uid, vals, context=None):
- """
- Create the Answer of survey and store in survey.response object, and if set validation of question then check the value of question if value is wrong then raise the exception.
- """
- if context is None: context = {}
-
- survey_question_wiz_id = super(survey_question_wiz,self).create(cr, uid, {'name': vals.get('name')}, context=context)
- if context.has_key('active') and context.get('active',False):
- return survey_question_wiz_id
-
- for key,val in vals.items():
- if key.split('_')[0] == "progress":
- vals.pop(key)
- if not context.has_key('sur_name_id') and key.split('_')[0] == "wizardid":
- context.update({'sur_name_id': int(key.split('_')[1])})
- vals.pop(key)
-
- click_state = True
- click_update = []
- surv_name_wiz = self.pool.get('survey.name.wiz')
- surv_all_resp_obj = self.pool.get('survey.response')
- surv_tbl_column_obj = self.pool.get('survey.tbl.column.heading')
- survey_obj = self.pool.get('survey')
- resp_obj = self.pool.get('survey.response.line')
- res_ans_obj = self.pool.get('survey.response.answer')
- que_obj = self.pool.get('survey.question')
- sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False), [])
- response_id = 0
-
- if not sur_name_read['response']:
- response_id = surv_all_resp_obj.create(cr, uid, {'response_type':'link', 'user_id':uid, 'date_create':datetime.datetime.now(), 'survey_id' : context['survey_id']})
- surv_name_wiz.write(cr, uid, [context.get('sur_name_id', False)], {'response' : tools.ustr(response_id)})
- else:
- response_id = int(sur_name_read['response'])
-
- if response_id not in surv_all_resp_obj.search(cr, uid, []):
- response_id = surv_all_resp_obj.create(cr, uid, {'response_type':'link', 'user_id':uid, 'date_create':datetime.datetime.now(), 'survey_id' : context.get('survey_id',False)})
- surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'response' : tools.ustr(response_id)})
-
- #click first time on next button then increemnet on total start suvey
- if not safe_eval(sur_name_read['store_ans']):
- his_id = self.pool.get('survey.history').create(cr, uid, {'user_id': uid, \
- 'date': strftime('%Y-%m-%d %H:%M:%S'), 'survey_id': sur_name_read['survey_id'][0]})
- survey_id = sur_name_read['survey_id'][0]
- sur_rec = survey_obj.read(cr, uid, survey_id)
- survey_obj.write(cr, uid, survey_id, {'tot_start_survey' : sur_rec['tot_start_survey'] + 1})
- if context.has_key('cur_id'):
- if context.has_key('request') and context.get('request',False):
- self.pool[context.get('object')].write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
- self.pool[context.get('object')].survey_req_done(cr, uid, [int(context.get('cur_id'))], context)
- else:
- self.pool[context.get('object')].write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
- if sur_name_read['store_ans'] and type(safe_eval(sur_name_read['store_ans'])) == dict:
- sur_name_read['store_ans'] = safe_eval(sur_name_read['store_ans'])
- for key,val in sur_name_read['store_ans'].items():
- for field in vals:
- if field.split('_')[0] == val['question_id']:
- click_state = False
- click_update.append(key)
- break
- else:
- sur_name_read['store_ans'] = {}
- if click_state:
- que_li = []
- resp_id_list = []
- for key, val in vals.items():
- que_id = key.split('_')[0]
- if que_id not in que_li:
- que_li.append(que_id)
- que_rec = que_obj.read(cr, uid, [int(que_id)], [])[0]
- res_data = {
- 'question_id': que_id,
- 'date_create': datetime.datetime.now(),
- 'state': 'done',
- 'response_id': response_id
- }
- resp_id = resp_obj.create(cr, uid, res_data)
- resp_id_list.append(resp_id)
- sur_name_read['store_ans'].update({resp_id:{'question_id':que_id}})
- surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
- select_count = 0
- numeric_sum = 0
- selected_value = []
- matrix_list = []
- comment_field = False
- comment_value = False
- response_list = []
-
- for key1, val1 in vals.items():
- if val1 and key1.split('_')[1] == "table" and key1.split('_')[0] == que_id:
- surv_tbl_column_obj.create(cr, uid, {'response_table_id' : resp_id,'column_id':key1.split('_')[2], 'name':key1.split('_')[3], 'value' : val1})
- sur_name_read['store_ans'][resp_id].update({key1:val1})
- select_count += 1
-
- elif val1 and key1.split('_')[1] == "otherfield" and key1.split('_')[0] == que_id:
- comment_field = True
- sur_name_read['store_ans'][resp_id].update({key1:val1})
- select_count += 1
- surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
- continue
-
- elif val1 and key1.split('_')[1] == "selection" and key1.split('_')[0] == que_id:
- if len(key1.split('_')) > 2:
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'column_id' : val1})
- selected_value.append(val1)
- response_list.append(str(ans_create_id) + "_" + str(key1.split('_')[-1]))
- else:
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':val1})
- sur_name_read['store_ans'][resp_id].update({key1:val1})
- select_count += 1
-
- elif key1.split('_')[1] == "other" and key1.split('_')[0] == que_id:
- if not val1:
- comment_value = True
- else:
- error = False
- if que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_specific_length':
- if (not val1 and que_rec['comment_minimum_no']) or len(val1) < que_rec['comment_minimum_no'] or len(val1) > que_rec['comment_maximum_no']:
- error = True
- elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
- error = False
- try:
- if que_rec['comment_valid_type'] == 'must_be_whole_number':
- value = int(val1)
- if value < que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
- error = True
- elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
- value = float(val1)
- if value < que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
- error = True
- elif que_rec['comment_valid_type'] == 'must_be_date':
- value = datetime.datetime.strptime(val1, "%Y-%m-%d")
- if value < datetime.datetime.strptime(que_rec['comment_minimum_date'], "%Y-%m-%d") or value > datetime.datetime.strptime(que_rec['comment_maximum_date'], "%Y-%m-%d"):
- error = True
- except:
- error = True
- elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_email_address':
- import re
- if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
- error = True
- if error:
- for res in resp_id_list:
- sur_name_read['store_ans'].pop(res)
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['comment_valid_err_msg']))
-
- resp_obj.write(cr, uid, resp_id, {'comment':val1})
- sur_name_read['store_ans'][resp_id].update({key1:val1})
-
- elif val1 and key1.split('_')[1] == "comment" and key1.split('_')[0] == que_id:
- resp_obj.write(cr, uid, resp_id, {'comment':val1})
- sur_name_read['store_ans'][resp_id].update({key1:val1})
- select_count += 1
-
- elif val1 and key1.split('_')[0] == que_id and (key1.split('_')[1] == "single" or (len(key1.split('_')) > 2 and key1.split('_')[2] == 'multi')):
- error = False
- if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
- if (not val1 and que_rec['validation_minimum_no']) or len(val1) < que_rec['validation_minimum_no'] or len(val1) > que_rec['validation_maximum_no']:
- error = True
- elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
- error = False
- try:
- if que_rec['validation_type'] == 'must_be_whole_number':
- value = int(val1)
- if value < que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
- error = True
- elif que_rec['validation_type'] == 'must_be_decimal_number':
- value = float(val1)
- if value < que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
- error = True
- elif que_rec['validation_type'] == 'must_be_date':
- value = datetime.datetime.strptime(val1, "%Y-%m-%d")
- if value < datetime.datetime.strptime(que_rec['validation_minimum_date'], "%Y-%m-%d") or value > datetime.datetime.strptime(que_rec['validation_maximum_date'], "%Y-%m-%d"):
- error = True
- except:
- error = True
- elif que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_email_address':
- import re
- if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
- error = True
- if error:
- for res in resp_id_list:
- sur_name_read['store_ans'].pop(res)
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['validation_valid_err_msg']))
-
- if key1.split('_')[1] == "single" :
- resp_obj.write(cr, uid, resp_id, {'single_text':val1})
- else:
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
-
- sur_name_read['store_ans'][resp_id].update({key1:val1})
- select_count += 1
-
- elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) > 2 and key1.split('_')[2] == 'numeric':
- if not val1=="0":
- try:
- numeric_sum += int(val1)
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
- sur_name_read['store_ans'][resp_id].update({key1:val1})
- select_count += 1
- except:
- for res in resp_id_list:
- sur_name_read['store_ans'].pop(res)
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + _("Please enter an integer value."))
-
- elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 3:
- if type(val1) == type('') or type(val1) == type(u''):
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'column_id' : key1.split('_')[2], 'value_choice' : val1})
- sur_name_read['store_ans'][resp_id].update({key1:val1})
- else:
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'column_id' : key1.split('_')[2]})
- sur_name_read['store_ans'][resp_id].update({key1:True})
-
- matrix_list.append(key1.split('_')[0] + '_' + key1.split('_')[1])
- select_count += 1
-
- elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 2:
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'answer' : val1})
- sur_name_read['store_ans'][resp_id].update({key1:val1})
- select_count += 1
- surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
-
- for key,val in vals.items():
- if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == que_id:
- for res_id in response_list:
- if key.split('_')[2] in res_id.split('_')[1]:
- a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
- sur_name_read['store_ans'][resp_id].update({key:val})
-
- if comment_field and comment_value:
- for res in resp_id_list:
- sur_name_read['store_ans'].pop(res)
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['make_comment_field_err_msg']))
-
- if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
- for res in resp_id_list:
- sur_name_read['store_ans'].pop(res)
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "'\n" + _("You cannot select the same answer more than one time."))
-
- if not select_count:
- resp_obj.write(cr, uid, resp_id, {'state':'skip'})
-
- if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
- for res in resp_id_list:
- sur_name_read['store_ans'].pop(res)
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg']))
-
- if que_rec['type'] in ['multiple_textboxes_diff_type', 'multiple_choice_multiple_ans','matrix_of_choices_only_one_ans','matrix_of_choices_only_multi_ans','matrix_of_drop_down_menus','rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time'] and que_rec['is_require_answer']:
- if matrix_list:
- if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
- (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
- (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
- (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
- (que_rec['required_type'] == 'a range' and (len(list(set(matrix_list))) < que_rec['minimum_req_ans'] or len(list(set(matrix_list))) > que_rec['maximum_req_ans'])):
- for res in resp_id_list:
- sur_name_read['store_ans'].pop(res)
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
-
- elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
- (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
- (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
- (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
- (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
- for res in resp_id_list:
- sur_name_read['store_ans'].pop(res)
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
-
- if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and que_rec['is_require_answer'] and select_count <= 0:
- for res in resp_id_list:
- sur_name_read['store_ans'].pop(res)
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
-
- else:
- resp_id_list = []
- for update in click_update:
- que_rec = que_obj.read(cr, uid , [int(sur_name_read['store_ans'][update]['question_id'])], [])[0]
- res_ans_obj.unlink(cr, uid,res_ans_obj.search(cr, uid, [('response_id', '=', update)]))
- surv_tbl_column_obj.unlink(cr, uid,surv_tbl_column_obj.search(cr, uid, [('response_table_id', '=', update)]))
- resp_id_list.append(update)
- sur_name_read['store_ans'].update({update:{'question_id':sur_name_read['store_ans'][update]['question_id']}})
- surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
- select_count = 0
- numeric_sum = 0
- selected_value = []
- matrix_list = []
- comment_field = False
- comment_value = False
- response_list = []
-
- for key, val in vals.items():
- ans_id_len = key.split('_')
- if ans_id_len[0] == sur_name_read['store_ans'][update]['question_id']:
- if val and key.split('_')[1] == "table":
- surv_tbl_column_obj.create(cr, uid, {'response_table_id' : update,'column_id':key.split('_')[2], 'name':key.split('_')[3], 'value' : val})
- sur_name_read['store_ans'][update].update({key:val})
- resp_obj.write(cr, uid, update, {'state': 'done'})
-
- elif val and key.split('_')[1] == "otherfield" :
- comment_field = True
- sur_name_read['store_ans'][update].update({key:val})
- select_count += 1
- surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
- continue
-
- elif val and key.split('_')[1] == "selection":
- if len(key.split('_')) > 2:
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':key.split('_')[-1], 'column_id' : val})
- selected_value.append(val)
- response_list.append(str(ans_create_id) + "_" + str(key.split('_')[-1]))
- else:
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id': val})
- resp_obj.write(cr, uid, update, {'state': 'done'})
- sur_name_read['store_ans'][update].update({key:val})
- select_count += 1
-
- elif key.split('_')[1] == "other":
- if not val:
- comment_value = True
- else:
- error = False
- if que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_specific_length':
- if (not val and que_rec['comment_minimum_no']) or len(val) < que_rec['comment_minimum_no'] or len(val) > que_rec['comment_maximum_no']:
- error = True
- elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
- try:
- if que_rec['comment_valid_type'] == 'must_be_whole_number':
- value = int(val)
- if value < que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
- error = True
- elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
- value = float(val)
- if value < que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
- error = True
- elif que_rec['comment_valid_type'] == 'must_be_date':
- value = datetime.datetime.strptime(val, "%Y-%m-%d")
- if value < datetime.datetime.strptime(que_rec['comment_minimum_date'], "%Y-%m-%d") or value > datetime.datetime.strptime(que_rec['comment_maximum_date'], "%Y-%m-%d"):
- error = True
- except:
- error = True
- elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_email_address':
- import re
- if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
- error = True
- if error:
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['comment_valid_err_msg']))
- resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
- sur_name_read['store_ans'][update].update({key:val})
-
- elif val and key.split('_')[1] == "comment":
- resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
- sur_name_read['store_ans'][update].update({key:val})
- select_count += 1
-
- elif val and (key.split('_')[1] == "single" or (len(key.split('_')) > 2 and key.split('_')[2] == 'multi')):
- error = False
- if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
- if (not val and que_rec['validation_minimum_no']) or len(val) < que_rec['validation_minimum_no'] or len(val) > que_rec['validation_maximum_no']:
- error = True
- elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
- error = False
- try:
- if que_rec['validation_type'] == 'must_be_whole_number':
- value = int(val)
- if value < que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
- error = True
- elif que_rec['validation_type'] == 'must_be_decimal_number':
- value = float(val)
- if value < que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
- error = True
- elif que_rec['validation_type'] == 'must_be_date':
- value = datetime.datetime.strptime(val, "%Y-%m-%d")
- if value < datetime.datetime.strptime(que_rec['validation_minimum_date'], "%Y-%m-%d") or value > datetime.datetime.strptime(que_rec['validation_maximum_date'], "%Y-%m-%d"):
- error = True
- except Exception ,e:
- error = True
- elif que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_email_address':
- import re
- if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
- error = True
- if error:
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['validation_valid_err_msg']))
- if key.split('_')[1] == "single" :
- resp_obj.write(cr, uid, update, {'single_text':val,'state': 'done'})
- else:
- resp_obj.write(cr, uid, update, {'state': 'done'})
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':ans_id_len[1], 'answer' : val})
- sur_name_read['store_ans'][update].update({key:val})
- select_count += 1
-
- elif val and len(key.split('_')) > 2 and key.split('_')[2] == 'numeric':
- if not val=="0":
- try:
- numeric_sum += int(val)
- resp_obj.write(cr, uid, update, {'state': 'done'})
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[1], 'answer' : val})
- sur_name_read['store_ans'][update].update({key:val})
- select_count += 1
- except:
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "'\n" + _("Please enter an integer value."))
-
- elif val and len(key.split('_')) == 3:
- resp_obj.write(cr, uid, update, {'state': 'done'})
- if type(val) == type('') or type(val) == type(u''):
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[1], 'column_id' : ans_id_len[2], 'value_choice' : val})
- sur_name_read['store_ans'][update].update({key:val})
- else:
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[1], 'column_id' : ans_id_len[2]})
- sur_name_read['store_ans'][update].update({key:True})
- matrix_list.append(key.split('_')[0] + '_' + key.split('_')[1])
- select_count += 1
-
- elif val and len(key.split('_')) == 2:
- resp_obj.write(cr, uid, update, {'state': 'done'})
- ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[-1], 'answer' : val})
- sur_name_read['store_ans'][update].update({key:val})
- select_count += 1
- surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans': sur_name_read['store_ans']})
-
- for key,val in vals.items():
- if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == sur_name_read['store_ans'][update]['question_id']:
- for res_id in response_list:
- if key.split('_')[2] in res_id.split('_')[1]:
- a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
- sur_name_read['store_ans'][update].update({key:val})
-
- if comment_field and comment_value:
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['make_comment_field_err_msg']))
-
- if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "\n" + _("You cannot select same answer more than one time.'"))
-
- if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg']))
-
- if not select_count:
- resp_obj.write(cr, uid, update, {'state': 'skip'})
-
- if que_rec['type'] in ['multiple_textboxes_diff_type','multiple_choice_multiple_ans','matrix_of_choices_only_one_ans','matrix_of_choices_only_multi_ans','matrix_of_drop_down_menus','rating_scale','multiple_textboxes','numerical_textboxes','date','date_and_time'] and que_rec['is_require_answer']:
- if matrix_list:
- if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
- (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
- (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
- (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
- (que_rec['required_type'] == 'a range' and (len(list(set(matrix_list))) < que_rec['minimum_req_ans'] or len(list(set(matrix_list))) > que_rec['maximum_req_ans'])):
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
-
- elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
- (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
- (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
- (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
- (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
-
- if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and que_rec['is_require_answer'] and select_count <= 0:
- raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
-
- return survey_question_wiz_id
-
- def action_new_question(self, cr, uid, ids, context=None):
- """
- New survey.Question form.
- """
- if context is None:
- context = {}
- for key,val in context.items():
- if type(key) == type(True):
- context.pop(key)
- view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),\
- ('name','=','survey_question_wizard_test')])
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'survey.question',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'view_id': view_id,
- 'page_id': int(context.get('page_id',0)),
- 'context': context
- }
-
- def action_new_page(self, cr, uid, ids, context=None):
- """
- New survey.Page form.
- """
- if context is None:
- context = {}
- for key,val in context.items():
- if type(key) == type(True):
- context.pop(key)
- view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),\
- ('name','=','survey_page_wizard_test')])
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'survey.page',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'view_id': view_id,
- 'context': context
- }
-
- def action_edit_page(self, cr, uid, ids, context=None):
- """
- Edit survey.page.
- """
- if context is None:
- context = {}
- for key,val in context.items():
- if type(key) == type(True):
- context.pop(key)
- view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),\
- ('name','=','survey_page_wizard_test')])
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'survey.page',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'res_id': int(context.get('page_id',0)),
- 'view_id': view_id,
- 'context': context
- }
-
- def action_delete_page(self, cr, uid, ids, context=None):
- """
- Delete survey.page.
- """
- if context is None:
- context = {}
- for key,val in context.items():
- if type(key) == type(True):
- context.pop(key)
-
- self.pool.get('survey.page').unlink(cr, uid, [context.get('page_id',False)])
- for survey in self.pool.get('survey').browse(cr, uid, [context.get('survey_id',False)], context=context):
- if not survey.page_ids:
- return {'type':'ir.actions.act_window_close'}
-
- search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),\
- ('name','=','Survey Search')])
- surv_name_wiz = self.pool.get('survey.name.wiz')
- surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], \
- {'transfer':True, 'page_no' : context.get('page_number',False) })
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'survey.question.wiz',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'search_view_id':search_id[0],
- 'context': context
- }
-
- def action_edit_question(self, cr, uid, ids, context=None):
- """
- Edit survey.question.
- """
- if context is None:
- context = {}
- for key,val in context.items():
- if type(key) == type(True):
- context.pop(key)
- view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),\
- ('name','=','survey_question_wizard_test')])
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'survey.question',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'res_id' : int(context.get('question_id',0)),
- 'view_id': view_id,
- 'context': context
- }
-
- def action_delete_question(self, cr, uid, ids, context=None):
- """
- Delete survey.question.
- """
- if context is None:
- context = {}
- for key,val in context.items():
- if type(key) == type(True):
- context.pop(key)
-
- que_obj = self.pool.get('survey.question')
- que_obj.unlink(cr, uid, [context.get('question_id',False)])
- search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),\
- ('name','=','Survey Search')])
- surv_name_wiz = self.pool.get('survey.name.wiz')
- surv_name_wiz.write(cr, uid, [context.get('sur_name_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',
- 'search_view_id': search_id[0],
- 'context': context
- }
-
- def action_forward_previous(self, cr, uid, ids, context=None):
- """
- Goes to previous Survey Answer.
- """
- if context is None:
- context = {}
- search_obj = self.pool.get('ir.ui.view')
- surv_name_wiz = self.pool.get('survey.name.wiz')
- search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
- ('name','=','Survey Search')])
- wiz_id = surv_name_wiz.create(cr,uid, {'survey_id': context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0})
- context.update({'sur_name_id' :wiz_id, 'response_no': context.get('response_no',0) - 1})
-
- if context.get('response_no',0) + 1 > len(context.get('response_id',0)):
- return {}
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'survey.question.wiz',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'search_view_id': search_id[0],
- 'context': context
- }
-
- def action_forward_next(self, cr, uid, ids, context=None):
- """
- Goes to Next Survey Answer.
- """
- if context is None:
- context = {}
- search_obj = self.pool.get('ir.ui.view')
- surv_name_wiz = self.pool.get('survey.name.wiz')
- search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
- ('name','=','Survey Search')])
- wiz_id = surv_name_wiz.create(cr,uid, {'survey_id' : context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0})
- context.update({'sur_name_id' :wiz_id, 'response_no' : context.get('response_no',0) + 1})
-
- if context.get('response_no',0) + 1 > len(context.get('response_id',0)):
- return {}
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'survey.question.wiz',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'search_view_id': search_id[0],
- 'context': context
- }
-
- def action_next(self, cr, uid, ids, context=None):
- """
- Goes to Next page.
- """
- if context is None:
- context = {}
- surv_name_wiz = self.pool.get('survey.name.wiz')
- search_obj = self.pool.get('ir.ui.view')
- search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
- surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'next'})
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'survey.question.wiz',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'search_view_id': search_id[0],
- 'context': context
- }
-
- def action_previous(self, cr, uid, ids, context=None):
- """
- Goes to previous page.
- """
- if context is None:
- context = {}
- surv_name_wiz = self.pool.get('survey.name.wiz')
- search_obj = self.pool.get('ir.ui.view')
- search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
- ('name','=','Survey Search')])
- surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'previous'})
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'survey.question.wiz',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'search_view_id': search_id[0],
- 'context': context
- }
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/survey/wizard/survey_answer.xml b/addons/survey/wizard/survey_answer.xml
deleted file mode 100644
index b02f9fb2be5..00000000000
--- a/addons/survey/wizard/survey_answer.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
- Survey Answer
- survey.question.wiz
-
-
-
-
-
-
-
-
- Survey Search
- survey.question.wiz
-
-
-
-
-
-
-
-
- ir.actions.act_window
- survey.question.wiz
- form
- form
- new
-
-
-
-
diff --git a/addons/survey/wizard/survey_browse_answer.py b/addons/survey/wizard/survey_browse_answer.py
deleted file mode 100644
index 1b461761bb5..00000000000
--- a/addons/survey/wizard/survey_browse_answer.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-TODAY OpenERP S.A.
-#
-# 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 .
-#
-##############################################################################
-
-from openerp.osv import fields, osv
-
-class survey_browse_answer(osv.osv_memory):
- _name = 'survey.browse.answer'
-
- _columns = {
- 'survey_id': fields.many2one('survey', "Survey", required="1"),
- 'response_id': fields.many2one("survey.response", "Survey Answers", help="If this field is empty, all answers of the selected survey will be print."),
- }
-
- def action_next(self, cr, uid, ids, context=None):
- """
- Open Browse Response wizard. if you select only survey_id then this wizard open with all response_ids and
- if you select survey_id and response_id then open the particular response of the survey.
- """
- if context is None: context = {}
- record = self.read(cr, uid, ids, [])
- record = record and record[0] or {}
- if record['response_id']:
- res_id = [(record.get('response_id') and record['response_id'][0])]
- else:
- sur_response_obj = self.pool.get('survey.response')
- res_id = sur_response_obj.search(cr, uid, [('survey_id', '=', record['survey_id'][0])])
- context.update({'active' : True,'survey_id' : record['survey_id'][0], 'response_id' : res_id, 'response_no' : 0})
- search_obj = self.pool.get('ir.ui.view')
- search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'survey.question.wiz',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'search_view_id':search_id[0],
- 'context' : context
- }
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/survey/wizard/survey_browse_answer.xml b/addons/survey/wizard/survey_browse_answer.xml
deleted file mode 100644
index 4f2adb85743..00000000000
--- a/addons/survey/wizard/survey_browse_answer.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
-
- Survey
- survey.browse.answer
-
-
-
-
-
-
-
-
-
-
-
-
- Answer Survey
- ir.actions.act_window
- survey.browse.answer
- form
- form
- new
-
-
-
-
-
-
diff --git a/addons/survey/wizard/survey_email_compose_message.py b/addons/survey/wizard/survey_email_compose_message.py
new file mode 100644
index 00000000000..22f204b9427
--- /dev/null
+++ b/addons/survey/wizard/survey_email_compose_message.py
@@ -0,0 +1,225 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2010-Today OpenERP SA ()
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see
+#
+##############################################################################
+
+from openerp.osv import osv
+from openerp.osv import fields
+from openerp.tools.translate import _
+from datetime import datetime
+
+import re
+import uuid
+import urlparse
+
+emails_split = re.compile(r"[;,\n\r]+")
+
+
+class survey_mail_compose_message(osv.TransientModel):
+ _name = 'survey.mail.compose.message'
+ _inherit = 'mail.compose.message'
+ _description = 'Email composition wizard for Survey'
+ _log_access = True
+
+ def _get_public_url(self, cr, uid, ids, name, arg, context=None):
+ res = dict((id, 0) for id in ids)
+ survey_obj = self.pool.get('survey.survey')
+ for wizard in self.browse(cr, uid, ids, context=context):
+ res[wizard.id] = survey_obj.browse(cr, uid, wizard.survey_id, context=context).public_url
+ return res
+
+ def _get_public_url_html(self, cr, uid, ids, name, arg, context=None):
+ """ Compute if the message is unread by the current user """
+ urls = self._get_public_url(cr, uid, ids, name, arg, context=context)
+ for key, url in urls.items():
+ urls[key] = '%s' % (url, _("Click here to start survey"))
+ return urls
+
+ _columns = {
+ 'survey_id': fields.many2one('survey.survey', 'Survey', required=True),
+ 'public': fields.selection([('public_link', 'Share the public web link to your audience.'),
+ ('email_public_link', 'Send by email the public web link to your audience.'),
+ ('email_private', 'Send private invitation to your audience (only one response per recipient and per invitation).')],
+ string='Share options', required=True),
+ 'public_url': fields.function(_get_public_url, string="Public url", type="char"),
+ 'public_url_html': fields.function(_get_public_url_html, string="Public HTML web link", type="char"),
+ 'partner_ids': fields.many2many('res.partner',
+ 'survey_mail_compose_message_res_partner_rel',
+ 'wizard_id', 'partner_id', 'Existing contacts'),
+ 'attachment_ids': fields.many2many('ir.attachment',
+ 'survey_mail_compose_message_ir_attachments_rel',
+ 'wizard_id', 'attachment_id', 'Attachments'),
+ 'multi_email': fields.text(string='List of emails', help="This list of emails of recipients will not converted in contacts. Emails separated by commas, semicolons or newline."),
+ 'date_deadline': fields.date(string="Deadline to which the invitation to respond is valid", help="Deadline to which the invitation to respond for this survey is valid. If the field is empty, the invitation is still valid."),
+ }
+
+ _defaults = {
+ 'public': 'public_link',
+ 'survey_id': lambda self, cr, uid, ctx={}: ctx.get('model') == 'survey.survey' and ctx.get('res_id') or None
+ }
+
+ def default_get(self, cr, uid, fields, context=None):
+ res = super(survey_mail_compose_message, self).default_get(cr, uid, fields, context=context)
+ if context.get('active_model') == 'res.partner' and context.get('active_ids'):
+ res.update({'partner_ids': context.get('active_ids')})
+ return res
+
+ def onchange_multi_email(self, cr, uid, ids, multi_email, context=None):
+ emails = list(set(emails_split.split(multi_email or "")))
+ emails_checked = []
+ error_message = ""
+ for email in emails:
+ email = email.strip()
+ if email:
+ if not re.search(r"^[^@]+@[^@]+$", email):
+ error_message += "\n'%s'" % email
+ else:
+ emails_checked.append(email)
+ if error_message:
+ raise osv.except_osv(_('Warning!'), _("One email at least is incorrect: %s" % error_message))
+
+ emails_checked.sort()
+ values = {'multi_email': '\n'.join(emails_checked)}
+ return {'value': values}
+
+ def onchange_survey_id(self, cr, uid, ids, survey_id, context=None):
+ """ Compute if the message is unread by the current user. """
+ if survey_id:
+ survey = self.pool.get('survey.survey').browse(cr, uid, survey_id, context=context)
+ return {
+ 'value': {
+ 'subject': survey.title,
+ 'public_url': survey.public_url,
+ 'public_url_html': '%s' % (survey.public_url, _("Click here to take survey")),
+ }}
+ else:
+ txt = _("Please select a survey")
+ return {
+ 'value': {
+ 'public_url': txt,
+ 'public_url_html': txt,
+ }}
+
+ #------------------------------------------------------
+ # Wizard validation and send
+ #------------------------------------------------------
+
+ def send_mail(self, cr, uid, ids, context=None):
+ """ Process the wizard content and proceed with sending the related
+ email(s), rendering any template patterns on the fly if needed """
+ if context is None:
+ context = {}
+
+ survey_response_obj = self.pool.get('survey.user_input')
+ partner_obj = self.pool.get('res.partner')
+ mail_mail_obj = self.pool.get('mail.mail')
+ try:
+ model, anonymous_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'portal', 'group_anonymous')
+ except ValueError:
+ anonymous_id = None
+
+ def create_response_and_send_mail(wizard, token, partner_id, email):
+ """ Create one mail by recipients and replace __URL__ by link with identification token """
+ #set url
+ url = wizard.survey_id.public_url
+
+ url = urlparse.urlparse(url).path[1:] # dirty hack to avoid incorrect urls
+
+ if token:
+ url = url + '/' + token
+
+ # post the message
+ values = {
+ 'model': None,
+ 'res_id': None,
+ 'subject': wizard.subject,
+ 'body': wizard.body.replace("__URL__", url),
+ 'body_html': wizard.body.replace("__URL__", url),
+ 'parent_id': None,
+ 'partner_ids': partner_id and [(4, partner_id)] or None,
+ 'notified_partner_ids': partner_id and [(4, partner_id)] or None,
+ 'attachment_ids': wizard.attachment_ids or None,
+ 'email_from': wizard.email_from or None,
+ 'email_to': email,
+ }
+ mail_id = mail_mail_obj.create(cr, uid, values, context=context)
+ mail_mail_obj.send(cr, uid, [mail_id], context=context)
+
+ def create_token(wizard, partner_id, email):
+ if context.get("survey_resent_token"):
+ response_ids = survey_response_obj.search(cr, uid, [('survey_id', '=', wizard.survey_id.id), ('state', 'in', ['new', 'skip']), '|', ('partner_id', '=', partner_id), ('email', '=', email)], context=context)
+ if response_ids:
+ return survey_response_obj.read(cr, uid, response_ids, ['token'], context=context)[0]['token']
+ if wizard.public != 'email_private':
+ return None
+ else:
+ token = uuid.uuid4().__str__()
+ # create response with token
+ survey_response_obj.create(cr, uid, {
+ 'survey_id': wizard.survey_id.id,
+ 'deadline': wizard.date_deadline,
+ 'date_create': datetime.now(),
+ 'type': 'link',
+ 'state': 'new',
+ 'token': token,
+ 'partner_id': partner_id,
+ 'email': email})
+ return token
+
+ for wizard in self.browse(cr, uid, ids, context=context):
+ # check if __URL__ is in the text
+ if wizard.body.find("__URL__") < 0:
+ raise osv.except_osv(_('Warning!'), _("The content of the text don't contain '__URL__'. \
+ __URL__ is automaticaly converted into the special url of the survey."))
+
+ if not wizard.multi_email and not wizard.partner_ids and (context.get('default_partner_ids') or context.get('default_multi_email')):
+ wizard.multi_email = context.get('default_multi_email')
+ wizard.partner_ids = context.get('default_partner_ids')
+
+ # quick check of email list
+ emails_list = []
+ if wizard.multi_email:
+ emails = list(set(emails_split.split(wizard.multi_email)) - set([partner.email for partner in wizard.partner_ids]))
+ for email in emails:
+ email = email.strip()
+ if re.search(r"^[^@]+@[^@]+$", email):
+ emails_list.append(email)
+
+ # remove public anonymous access
+ partner_list = []
+ for partner in wizard.partner_ids:
+ if not anonymous_id or not partner.user_ids or anonymous_id not in [x.id for x in partner.user_ids[0].groups_id]:
+ partner_list.append({'id': partner.id, 'email': partner.email})
+
+ if not len(emails_list) and not len(partner_list):
+ if wizard.model == 'res.partner' and wizard.res_id:
+ return False
+ raise osv.except_osv(_('Warning!'), _("Please enter at least one valid recipient."))
+
+ for email in emails_list:
+ partner_id = partner_obj.search(cr, uid, [('email', '=', email)], context=context)
+ partner_id = partner_id and partner_id[0] or None
+ token = create_token(wizard, partner_id, email)
+ create_response_and_send_mail(wizard, token, partner_id, email)
+
+ for partner in partner_list:
+ token = create_token(wizard, partner['id'], partner['email'])
+ create_response_and_send_mail(wizard, token, partner['id'], partner['email'])
+
+ return {'type': 'ir.actions.act_window_close'}
diff --git a/addons/survey/wizard/survey_email_compose_message.xml b/addons/survey/wizard/survey_email_compose_message.xml
new file mode 100644
index 00000000000..cef59019945
--- /dev/null
+++ b/addons/survey/wizard/survey_email_compose_message.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+ Survey - Send by Email
+
+
+
+
+
Hello,
+
We are conducting a survey, and your response would be appreciated.
+ You can share your survey web public link and/or send private invitations to your audience. People can answer once per invitation, and whenever they want with the public web link (in this case, the "Public in website" setting must be enabled).
+
+
Copy, paste and share the web link below to your audience.
+
+
Copy and paste the HTML code below to add this web link to any webpage.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/survey/wizard/survey_print.py b/addons/survey/wizard/survey_print.py
deleted file mode 100644
index f0e39f99cb9..00000000000
--- a/addons/survey/wizard/survey_print.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-TODAY OpenERP S.A.
-#
-# 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 .
-#
-##############################################################################
-
-from openerp.osv import fields, osv
-from openerp.tools.translate import _
-
-class survey_print(osv.osv_memory):
- _name = 'survey.print'
- _columns = {
- 'survey_ids': fields.many2many('survey', string="Survey", required="1"),
- 'orientation' : fields.selection([('vertical','Portrait(Vertical)'),\
- ('horizontal','Landscape(Horizontal)')], 'Orientation'),
- 'paper_size' : fields.selection([('letter','Letter (8.5" x 11")'),\
- ('legal','Legal (8.5" x 14")'),('a4','A4 (210mm x 297mm)')], 'Paper Size'),
- 'page_number' : fields.boolean('Include Page Number'),
- 'without_pagebreak' : fields.boolean('Print Without Page Breaks'),
- }
-
- _defaults = {
- 'orientation': lambda *a:'vertical',
- 'paper_size': lambda *a:'letter',
- 'page_number':lambda *a: 0,
- 'without_pagebreak':lambda *a: 0
- }
-
- def action_next(self, cr, uid, ids, context=None):
- """
- Print Survey Form(print template of the survey).
-
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of Survey IDs
- @param context: A standard dictionary for contextual values
- @return : Dictionary value for print survey form.
- """
- datas = {'ids' : self.read(cr, uid, ids, ['survey_ids'], context=context)[0]['survey_ids']}
- res = self.read(cr, uid, ids, ['survey_title', 'orientation', 'paper_size',\
- 'page_number', 'without_pagebreak'], context=context)
- res = res and res[0] or {}
- datas['form'] = res
- datas['model'] = 'survey.print'
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'survey.form',
- 'datas': datas,
- }
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/survey/wizard/survey_print.xml b/addons/survey/wizard/survey_print.xml
deleted file mode 100644
index b539b844654..00000000000
--- a/addons/survey/wizard/survey_print.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
- Survey Print
- survey.print
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Print Survey
- survey.print
- form
- form
- new
-
-
-
-
-
-
diff --git a/addons/survey/wizard/survey_print_answer.py b/addons/survey/wizard/survey_print_answer.py
deleted file mode 100644
index 417d1bb732f..00000000000
--- a/addons/survey/wizard/survey_print_answer.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-TODAY OpenERP S.A.
-#
-# 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 .
-#
-##############################################################################
-
-from openerp.osv import fields, osv
-from openerp.tools.translate import _
-
-class survey_print_answer(osv.osv_memory):
- _name = 'survey.print.answer'
- _columns = {
- 'response_ids': fields.many2many('survey.response','survey_print_response',\
- 'response_id','print_id', "Answer", required="1"),
- 'orientation': fields.selection([('vertical','Portrait(Vertical)'),\
- ('horizontal','Landscape(Horizontal)')], 'Orientation'),
- 'paper_size': fields.selection([('letter','Letter (8.5" x 11")'),\
- ('legal','Legal (8.5" x 14")'),\
- ('a4','A4 (210mm x 297mm)')], 'Paper Size'),
- 'page_number': fields.boolean('Include Page Number'),
- 'without_pagebreak': fields.boolean('Print Without Page Breaks')
- }
-
- _defaults = {
- 'orientation': lambda *a:'vertical',
- 'paper_size': lambda *a:'letter',
- 'page_number': lambda *a: 0,
- 'without_pagebreak': lambda *a: 0
- }
-
- def action_next(self, cr, uid, ids, context=None):
- """
- Print Survey Answer in pdf format.
-
- @param self: The object pointer
- @param cr: the current row, from the database cursor,
- @param uid: the current user’s ID for security checks,
- @param ids: List of print answer IDs
- @param context: A standard dictionary for contextual values
- @return : Dictionary value for created survey answer report
- """
- if context is None:
- context = {}
- datas = {'ids': context.get('active_ids', [])}
- res = self.read(cr, uid, ids, ['response_ids', 'orientation', 'paper_size',\
- 'page_number', 'without_pagebreak'], context=context)
- res = res and res[0] or {}
- datas['form'] = res
- datas['model'] = 'survey.print.answer'
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'survey.browse.response',
- 'datas': datas,
- }
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/survey/wizard/survey_print_answer.xml b/addons/survey/wizard/survey_print_answer.xml
deleted file mode 100644
index f3c8d01a62c..00000000000
--- a/addons/survey/wizard/survey_print_answer.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
- Survey Print Answer
- survey.print.answer
-
-
-
-
-
-
-
-
- Survey Print Statistics
- survey.print.statistics
- form
- form
- new
-
-
-
-
-
-
diff --git a/addons/survey/wizard/survey_selection.py b/addons/survey/wizard/survey_selection.py
deleted file mode 100644
index a8f83ba0361..00000000000
--- a/addons/survey/wizard/survey_selection.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-TODAY OpenERP S.A.
-#
-# 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 .
-#
-##############################################################################
-
-from lxml import etree
-
-from openerp.osv import fields, osv
-from openerp.tools.translate import _
-
-class survey_name_wiz(osv.osv_memory):
- _name = 'survey.name.wiz'
-
- _columns = {
- 'survey_id': fields.many2one('survey', 'Survey', required=True, ondelete='cascade', domain= [('state', '=', 'open')]),
- 'page_no': fields.integer('Page Number'),
- 'note': fields.text("Description"),
- 'page': fields.char('Page Position',size = 12),
- 'transfer': fields.boolean('Page Transfer'),
- 'store_ans': fields.text('Store Answer'),
- 'response': fields.char('Answer',size=16)
- }
- _defaults = {
- 'page_no': -1,
- 'page': 'next',
- 'transfer': 1,
- 'response': 0,
- 'survey_id': lambda self,cr,uid,context:context.get('survey_id',False),
- 'store_ans': '{}' #Setting the default pattern as '{}' as the field is of type text. The field always gets the value in dict format
- }
-
- def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
- res = super(survey_name_wiz, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=False)
- if uid != 1:
- survey_obj = self.pool.get('survey')
- line_ids = survey_obj.search(cr, uid, [('invited_user_ids','in',uid)], context=context)
- domain = str([('id', 'in', line_ids)])
- doc = etree.XML(res['arch'])
- nodes = doc.xpath("//field[@name='survey_id']")
- for node in nodes:
- node.set('domain', domain)
- res['arch'] = etree.tostring(doc)
- return res
-
- def action_next(self, cr, uid, ids, context=None):
- """
- Start the survey, Increment in started survey field but if set the max_response_limit of
- survey then check the current user how many times start this survey. if current user max_response_limit
- is reach then this user can not start this survey(Raise Exception).
- """
- survey_obj = self.pool.get('survey')
- search_obj = self.pool.get('ir.ui.view')
- if context is None: context = {}
-
- this = self.browse(cr, uid, ids, context=context)[0]
- survey_id = this.survey_id.id
- context.update({'survey_id': survey_id, 'sur_name_id': this.id})
- cr.execute('select count(id) from survey_history where user_id=%s\
- and survey_id=%s' % (uid,survey_id))
-
- res = cr.fetchone()[0]
- sur_rec = survey_obj.browse(cr,uid,survey_id,context=context)
- if sur_rec.response_user and res >= sur_rec.response_user:
- raise osv.except_osv(_('Warning!'),_("You cannot give response for this survey more than %s times.") % (sur_rec.response_user))
-
- if sur_rec.max_response_limit and sur_rec.max_response_limit <= sur_rec.tot_start_survey:
- raise osv.except_osv(_('Warning!'),_("You cannot give more responses. Please contact the author of this survey for further assistance."))
-
- search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
- return {
- 'view_type': 'form',
- "view_mode": 'form',
- 'res_model': 'survey.question.wiz',
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'search_view_id': search_id[0],
- 'context': context
- }
-
- def on_change_survey(self, cr, uid, ids, survey_id, context=None):
- """
- on change event of survey_id field, if note is available in selected survey then display this note in note fields.
- """
- if not survey_id:
- return {}
- notes = self.pool.get('survey').read(cr, uid, survey_id, ['note'])['note']
- return {'value': {'note': notes}}
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/survey/wizard/survey_selection.xml b/addons/survey/wizard/survey_selection.xml
deleted file mode 100644
index 56f5f5cda33..00000000000
--- a/addons/survey/wizard/survey_selection.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
- Survey
- survey.name.wiz
-
-
-
-
-
-
-
-
-
-
-
-
- Give Survey Answer
- ir.actions.act_window
- survey.name.wiz
- form
- form
- new
-
-
-
diff --git a/addons/survey/wizard/survey_send_invitation.py b/addons/survey/wizard/survey_send_invitation.py
deleted file mode 100644
index e16d0d6ce77..00000000000
--- a/addons/survey/wizard/survey_send_invitation.py
+++ /dev/null
@@ -1,233 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL ()
-#
-# 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
-#
-##############################################################################
-
-import time
-from random import choice
-import string
-import os
-import datetime
-import socket
-
-from openerp import tools
-from openerp.modules.module import get_module_resource
-from openerp.osv import fields, osv
-import openerp.report
-from openerp.tools.translate import _
-
-
-class survey_send_invitation(osv.osv_memory):
- _name = 'survey.send.invitation'
- _columns = {
- 'partner_ids': fields.many2many('res.partner','survey_res_partner','partner_id',\
- 'survey_id', "Answer", required=1),
- 'send_mail': fields.boolean('Send Mail for New User'),
- 'send_mail_existing': fields.boolean('Send Reminder for Existing User'),
- 'mail_subject': fields.char('Subject', size=256),
- 'mail_subject_existing': fields.char('Subject', size=256),
- 'mail_from': fields.char('From', size=256, required=1),
- 'mail': fields.text('Body')
- }
-
- _defaults = {
- 'send_mail': lambda *a: 1,
- 'send_mail_existing': lambda *a: 1,
- }
-
- def genpasswd(self):
- chars = string.letters + string.digits
- return ''.join([choice(chars) for i in range(6)])
-
- def default_get(self, cr, uid, fields_list, context=None):
- if context is None:
- context = {}
- data = super(survey_send_invitation, self).default_get(cr, uid, fields_list, context)
- survey_obj = self.pool.get('survey')
- msg = ""
- name = ""
- for sur in survey_obj.browse(cr, uid, context.get('active_ids', []), context=context):
- name += "\n --> " + sur.title + "\n"
- if sur.state != 'open':
- msg += sur.title + "\n"
- data['mail_subject'] = _("Invitation for %s") % (sur.title)
- data['mail_subject_existing'] = _("Invitation for %s") % (sur.title)
- data['mail_from'] = sur.responsible_id.email
- if msg:
- raise osv.except_osv(_('Warning!'), _('The following surveys are not in open state: %s') % msg)
- data['mail'] = _('''
-Hello %%(name)s, \n\n
-Would you please spent some of your time to fill-in our survey: \n%s\n
-You can access this survey with the following parameters:
- URL: %s
- Your login ID: %%(login)s\n
- Your password: %%(passwd)s\n
-\n\n
-Thanks,''') % (name, self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='http://localhost:8069', context=context))
- return data
-
- def create_report(self, cr, uid, res_ids, report_name=False, file_name=False):
- if not report_name or not res_ids:
- return (False, Exception('Report name and Resources ids are required !!!'))
- try:
- ret_file_name = get_module_resource('survey', 'report') + file_name + '.pdf'
- result, format = openerp.report.render_report(cr, uid, res_ids, report_name[len('report.'):], {}, {})
- fp = open(ret_file_name, 'wb+');
- fp.write(result);
- fp.close();
- except Exception,e:
- print 'Exception in create report:',e
- return (False, str(e))
- return (True, ret_file_name)
-
-
- def action_send(self, cr, uid, ids, context=None):
- if context is None:
- context = {}
- record = self.read(cr, uid, ids, [],context=context)
- survey_ids = context.get('active_ids', [])
- record = record and record[0]
- partner_ids = record['partner_ids']
- user_ref= self.pool.get('res.users')
- survey_ref= self.pool.get('survey')
- mail_message = self.pool.get('mail.message')
-
- model_data_obj = self.pool.get('ir.model.data')
- group_id = model_data_obj._get_id(cr, uid, 'base', 'group_survey_user')
- group_id = model_data_obj.browse(cr, uid, group_id, context=context).res_id
-
- act_id = self.pool.get('ir.actions.act_window')
- act_id = act_id.search(cr, uid, [('res_model', '=' , 'survey.name.wiz'), \
- ('view_type', '=', 'form')])
- out = "login,password\n"
- skipped = 0
- existing = ""
- created = ""
- error = ""
- new_user = []
- attachments = {}
- current_sur = survey_ref.browse(cr, uid, context.get('active_id'), context=context)
- exist_user = current_sur.invited_user_ids
- if exist_user:
- for use in exist_user:
- new_user.append(use.id)
- for id in survey_ref.browse(cr, uid, survey_ids):
- result, format = openerp.report.render_report(cr, uid, [id.id], 'survey.form', {}, {})
- attachments[id.title +".pdf"] = result
-
- for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids):
- if not partner.email:
- skipped+= 1
- continue
- user = user_ref.search(cr, uid, [('partner_id', "=", partner.id)])
- if user:
- if user[0] not in new_user:
- new_user.append(user[0])
- user = user_ref.browse(cr, uid, user[0])
- user_ref.write(cr, uid, user.id, {'survey_id':[[6, 0, survey_ids]]})
- mail = record['mail']%{'login':partner.email, 'passwd':user.password, \
- 'name' : partner.name}
- if record['send_mail_existing']:
- vals = {
- 'state': 'outgoing',
- 'subject': record['mail_subject_existing'],
- 'body_html': '
-
-
-
-
-
-
- survey.send.invitation.log
- survey.send.invitation.log
- form
- form
- new
-
-
-
diff --git a/addons/survey_crm/__init__.py b/addons/survey_crm/__init__.py
new file mode 100644
index 00000000000..e31f63c9bd2
--- /dev/null
+++ b/addons/survey_crm/__init__.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2011 OpenERP S.A ().
+#
+# 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 .
+#
+##############################################################################
+
+import survey
diff --git a/addons/survey/wizard/survey_print_statistics.py b/addons/survey_crm/__openerp__.py
similarity index 51%
rename from addons/survey/wizard/survey_print_statistics.py
rename to addons/survey_crm/__openerp__.py
index d005dbee31a..1b9fba3d680 100644
--- a/addons/survey/wizard/survey_print_statistics.py
+++ b/addons/survey_crm/__openerp__.py
@@ -1,8 +1,8 @@
-# -*- encoding: utf-8 -*-
+# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-TODAY OpenERP S.A.
+# Copyright (C) 2004-2010 Tiny SPRL ().
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -19,31 +19,23 @@
#
##############################################################################
-from openerp.osv import fields, osv
-from openerp.tools.translate import _
-
-class survey_print_statistics(osv.osv_memory):
- _name = 'survey.print.statistics'
- _columns = {
- 'survey_ids': fields.many2many('survey', string="Survey", required="1"),
- }
-
- def action_next(self, cr, uid, ids, context=None):
- """
- Print Survey Statistics in pdf format.
- """
- if context is None:
- context = {}
- datas = {'ids': context.get('active_ids', [])}
- res = self.read(cr, uid, ids, ['survey_ids'], context=context)
- res = res and res[0] or {}
- datas['form'] = res
- datas['model'] = 'survey.print.statistics'
- return {
- 'type': 'ir.actions.report.xml',
- 'report_name': 'survey.analysis',
- 'datas': datas,
- }
-
+{
+ 'name': 'Survey CRM',
+ 'version': '2.0',
+ 'category': 'Marketing',
+ 'complexity': 'easy',
+ 'description': """
+Survey - CRM (bridge module)
+=================================================================================
+This module adds a Survey mass mailing button inside the more option of lead/customers views
+""",
+ 'author': 'OpenERP SA',
+ 'depends': ['crm', 'survey'],
+ 'data': [
+ 'crm_view.xml',
+ ],
+ 'installable': True,
+ 'auto_install': True
+}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/survey_crm/crm_view.xml b/addons/survey_crm/crm_view.xml
new file mode 100644
index 00000000000..d28840643f6
--- /dev/null
+++ b/addons/survey_crm/crm_view.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/addons/survey_crm/survey.py b/addons/survey_crm/survey.py
new file mode 100644
index 00000000000..6c7c22bcf11
--- /dev/null
+++ b/addons/survey_crm/survey.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2011 OpenERP S.A ().
+#
+# 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 .
+#
+##############################################################################
+
+from openerp.osv import osv
+
+
+class survey_mail_compose_message(osv.TransientModel):
+ _inherit = 'survey.mail.compose.message'
+
+ def default_get(self, cr, uid, fields, context=None):
+ res = super(survey_mail_compose_message, self).default_get(cr, uid, fields, context=context)
+ if context.get('active_model') == 'crm.lead' and context.get('active_ids'):
+ partner_ids = []
+ emails_list = []
+ for lead in self.pool.get('crm.lead').browse(cr, uid, context.get('active_ids'), context=context):
+ if lead.partner_id:
+ partner_ids.append(lead.partner_id.id)
+ else:
+ email = lead.contact_name and "%s <%s>" % (lead.contact_name, lead.email_from or "") or lead.email_from or None
+ if email and email not in emails_list:
+ emails_list.append(email)
+ multi_email = "\n".join(emails_list)
+
+ res.update({'partner_ids': list(set(partner_ids)), 'multi_email': multi_email})
+ return res
diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml
index a9a9173099a..5ea48d92a31 100644
--- a/addons/website/views/website_templates.xml
+++ b/addons/website/views/website_templates.xml
@@ -69,6 +69,7 @@
+