1 ## -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
25 from lxml import etree
27 from time import strftime
29 from openerp import addons, netsvc, tools
30 from openerp.osv import fields, osv
31 from openerp.tools import to_xml, SUPERUSER_ID
32 from openerp.tools.translate import _
33 from openerp.tools.safe_eval import safe_eval
35 class survey_question_wiz(osv.osv_memory):
36 _name = 'survey.question.wiz'
38 'name': fields.integer('Number'),
41 def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
43 Fields View Get method :- generate the new view and display the survey pages of selected survey.
47 result = super(survey_question_wiz, self).fields_view_get(cr, uid, view_id, \
48 view_type, context, toolbar,submenu)
50 surv_name_wiz = self.pool.get('survey.name.wiz')
51 survey_obj = self.pool.get('survey')
52 page_obj = self.pool.get('survey.page')
53 que_obj = self.pool.get('survey.question')
54 ans_obj = self.pool.get('survey.answer')
55 sur_response_obj = self.pool.get('survey.response')
56 que_col_head = self.pool.get('survey.question.column.heading')
57 user_obj = self.pool.get('res.users')
58 mail_message = self.pool.get('mail.message')
60 if view_type in ['form']:
63 if 'sur_name_id' in context:
64 sur_name_rec = surv_name_wiz.browse(cr, uid, context['sur_name_id'], context=context)
65 elif 'survey_id' in context:
67 'survey_id': context.get('survey_id', False),
73 wiz_id = surv_name_wiz.create(cr, uid, res_data)
74 sur_name_rec = surv_name_wiz.browse(cr, uid, wiz_id, context=context)
75 context.update({'sur_name_id' :wiz_id})
77 if context.has_key('active_id'):
78 context.pop('active_id')
80 survey_id = context.get('survey_id', False)
82 # Try one more time to find it
83 if sur_name_rec and sur_name_rec.survey_id:
84 survey_id = sur_name_rec.survey_id.id
86 # raise osv.except_osv(_('Error!'), _("Cannot locate survey for the question wizard!"))
87 # If this function is called without a survey_id in
88 # its context, it makes no sense to return any view.
89 # Just return the default, empty view for this object,
90 # in order to please random calls to this fn().
91 return super(survey_question_wiz, self).\
92 fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context,
93 toolbar=toolbar, submenu=submenu)
94 sur_rec = survey_obj.browse(cr, uid, survey_id, context=context)
95 p_id = map(lambda x:x.id, sur_rec.page_ids)
96 total_pages = len(p_id)
100 if context.get('response_id', False) \
101 and int(context['response_id'][0]) > 0:
104 if not sur_name_rec.page_no + 1 :
105 surv_name_wiz.write(cr, uid, [context['sur_name_id'],], {'store_ans':{}})
107 sur_name_read = surv_name_wiz.browse(cr, uid, context['sur_name_id'], context=context)
108 page_number = int(sur_name_rec.page_no)
109 if sur_name_read.transfer or not sur_name_rec.page_no + 1:
110 surv_name_wiz.write(cr, uid, [context['sur_name_id']], {'transfer':False})
113 if sur_name_read.page == "next" or sur_name_rec.page_no == -1:
114 if total_pages > sur_name_rec.page_no + 1:
115 if ((context.has_key('active') and not context.get('active', False)) \
116 or not context.has_key('active')) and not sur_name_rec.page_no + 1:
117 if sur_rec.state != "open" :
118 raise osv.except_osv(_('Warning!'),_("You cannot answer because the survey is not open."))
119 cr.execute('select count(id) from survey_history where user_id=%s\
120 and survey_id=%s', (uid,survey_id))
121 res = cr.fetchone()[0]
122 user_limit = survey_obj.browse(cr, uid, survey_id)
123 user_limit = user_limit.response_user
124 if user_limit and res >= user_limit:
125 raise osv.except_osv(_('Warning!'),_("You cannot answer this survey more than %s times.") % (user_limit))
127 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:
128 survey_obj.write(cr, SUPERUSER_ID, survey_id, {'state':'close', 'date_close':strftime("%Y-%m-%d %H:%M:%S")})
130 p_id = p_id[sur_name_rec.page_no + 1]
131 surv_name_wiz.write(cr, uid, [context['sur_name_id'],], {'page_no' : sur_name_rec.page_no + 1})
134 if sur_name_rec.page_no > - 1:
139 if sur_name_rec.page_no != 0:
140 p_id = p_id[sur_name_rec.page_no - 1]
141 surv_name_wiz.write(cr, uid, [context['sur_name_id'],],\
142 {'page_no' : sur_name_rec.page_no - 1})
146 if sur_name_rec.page_no > 1:
149 pag_rec = page_obj.browse(cr, uid, p_id, context=context)
153 title = pag_rec.title
155 question_ids = pag_rec.question_ids
157 title = sur_rec.title
158 xml_form = etree.Element('form', {'string': tools.ustr(title)})
159 if context.has_key('active') and context.get('active',False) and context.has_key('edit'):
160 context.update({'page_id' : p_id,'page_number' : sur_name_rec.page_no , 'transfer' : sur_name_read.transfer})
161 xml_group3 = etree.SubElement(xml_form, 'group', {'col': '4', 'colspan': '4'})
162 etree.SubElement(xml_group3, 'button', {'string' :'Add Page','icon': "gtk-new", 'type' :'object','name':"action_new_page", 'context' : tools.ustr(context)})
163 etree.SubElement(xml_group3, 'button', {'string' :'Edit Page','icon': "gtk-edit", 'type' :'object','name':"action_edit_page", 'context' : tools.ustr(context)})
164 etree.SubElement(xml_group3, 'button', {'string' :'Delete Page','icon': "gtk-delete", 'type' :'object','name':"action_delete_page", 'context' : tools.ustr(context)})
165 etree.SubElement(xml_group3, 'button', {'string' :'Add Question','icon': "gtk-new", 'type' :'object','name':"action_new_question", 'context' : tools.ustr(context)})
170 if context.has_key('response_id') and context.get('response_id', False) \
171 and int(context.get('response_id',0)[0]) > 0:
172 # TODO: l10n, cleanup this code to make it readable. Or template?
173 xml_group = etree.SubElement(xml_form, 'group', {'col': '40', 'colspan': '4'})
174 record = sur_response_obj.browse(cr, uid, context['response_id'][context['response_no']])
175 timezone = pytz.timezone(context.get('tz') or 'UTC')
176 response_date = pytz.UTC.localize(datetime.datetime.strptime(record['date_create'].split('.')[0], tools.DEFAULT_SERVER_DATETIME_FORMAT))
177 localized_response_date = response_date.astimezone(timezone)
178 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(_('Answer Of :- ') + record.user_id.name + _(', Date :- ') + localized_response_date.strftime("%Y-%m-%d %H:%M:%S") )), 'align':"0.0"})
179 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"})
180 if context.get('response_no',0) > 0:
181 etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_forward_previous",'string': tools.ustr("Previous Answer"),'type':"object"})
182 if context.get('response_no',0) + 1 < len(context.get('response_id',0)):
183 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)})
186 fields["wizardid_" + str(wiz_id)] = {'type':'char', 'size' : 255, 'string':"", 'views':{}}
187 etree.SubElement(xml_form, 'field', {'invisible':'1','name': "wizardid_" + str(wiz_id),'default':str(lambda *a: 0),'modifiers':'{"invisible":true}'})
190 xml_group_note = etree.SubElement(xml_form, 'group', {'col': '1','colspan': '4'})
191 for que_test in note.split('\n'):
192 etree.SubElement(xml_group_note, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
193 que_ids = question_ids
198 que_rec = que_obj.browse(cr, uid, que.id, context=context)
199 descriptive_text = ""
200 separator_string = tools.ustr(qu_no) + "." + tools.ustr(que_rec.question)
201 if ((context.has_key('active') and not context.get('active',False)) or not context.has_key('active')) and que_rec.is_require_answer:
205 if context.has_key('active') and context.get('active',False) and \
206 context.has_key('edit'):
207 etree.SubElement(xml_form, 'separator', {'string': star+to_xml(separator_string)})
209 xml_group1 = etree.SubElement(xml_form, 'group', {'col': '2', 'colspan': '2'})
210 context.update({'question_id' : tools.ustr(que.id),'page_number': sur_name_rec.page_no , 'transfer' : sur_name_read.transfer, 'page_id' : p_id})
211 etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-edit", 'type' :'object', 'name':"action_edit_question", 'context' : tools.ustr(context)})
212 etree.SubElement(xml_group1, 'button', {'string':'','icon': "gtk-delete", 'type' :'object','name':"action_delete_question", 'context' : tools.ustr(context)})
214 etree.SubElement(xml_form, 'newline')
215 etree.SubElement(xml_form, 'separator', {'string': star+to_xml(separator_string)})
217 ans_ids = que_rec.answer_choice_ids
218 xml_group = etree.SubElement(xml_form, 'group', {'col': '1', 'colspan': '4'})
220 if que_rec.type == 'multiple_choice_only_one_ans':
223 selection.append((tools.ustr(ans.id), ans.answer))
224 xml_group = etree.SubElement(xml_group, 'group', {'col': '2', 'colspan': '2'})
225 etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_selection"})
226 fields[tools.ustr(que.id) + "_selection"] = {'type':'selection', 'selection' :selection, 'string':_('Answer')}
228 elif que_rec.type == 'multiple_choice_multiple_ans':
229 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
231 etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
232 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'boolean', 'string':ans.answer}
234 elif que_rec.type in ['matrix_of_choices_only_one_ans', 'rating_scale']:
235 if que_rec.comment_column:
241 xml_group = etree.SubElement(xml_group, 'group', {'col': tools.ustr(col), 'colspan': tools.ustr(colspan)})
243 etree.SubElement(xml_group, 'newline')
244 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))})
245 selection = [('','')]
246 for col in que_rec.column_heading_ids:
247 selection.append((str(col.id), col.title))
248 fields[tools.ustr(que.id) + "_selection_" + tools.ustr(row.id)] = {'type':'selection', 'selection' : selection, 'string': "Answer"}
249 if que_rec.comment_column:
250 fields[tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id) + "_field"] = {'type':'char', 'size' : 255, 'string':tools.ustr(que_rec.column_name), 'views':{}}
251 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_commentcolumn_"+tools.ustr(row.id)+ "_field"})
253 elif que_rec.type == 'matrix_of_choices_only_multi_ans':
254 xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
255 etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
256 for col in que_rec.column_heading_ids:
257 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
259 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer)) +' :-', 'align': '0.0'})
260 for col in que_col_head.browse(cr, uid, [head.id for head in que_rec.column_heading_ids]):
261 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id), 'nolabel':"1"})
262 fields[tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id)] = {'type':'boolean', 'string': col.title}
264 elif que_rec.type == 'matrix_of_drop_down_menus':
265 xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids) + 1), 'colspan': '4'})
266 etree.SubElement(xml_group, 'separator', {'string': '.','colspan': '1'})
267 for col in que_rec.column_heading_ids:
268 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
270 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(row.answer))+' :-', 'align': '0.0'})
271 for col in que_rec.column_heading_ids:
274 for item in col.menu_choice.split('\n'):
275 if item and not item.strip() == '': selection.append((item ,item))
276 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id),'nolabel':'1'})
277 fields[tools.ustr(que.id) + "_" + tools.ustr(row.id) + "_" + tools.ustr(col.id)] = {'type':'selection', 'string': col.title, 'selection':selection}
279 elif que_rec.type == 'multiple_textboxes':
280 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
282 if que_rec.is_validation_require:
283 if que_rec.validation_type in ['must_be_whole_number']:
285 elif que_rec.validation_type in ['must_be_decimal_number']:
287 elif que_rec.validation_type in ['must_be_date']:
290 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
292 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
294 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(type), 'string':ans.answer}
296 elif que_rec.type == 'numerical_textboxes':
297 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
299 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"})
300 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_numeric"] = {'type':'integer', 'string':ans.answer}
302 elif que_rec.type == 'date':
303 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
305 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
306 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'date', 'string':ans.answer}
308 elif que_rec.type == 'date_and_time':
309 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
311 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id)})
312 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id)] = {'type':'datetime', 'string':ans.answer}
314 elif que_rec.type == 'descriptive_text':
315 if que_rec.descriptive_text:
316 for que_test in que_rec.descriptive_text.split('\n'):
317 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_test)), 'align':"0.0"})
319 elif que_rec.type == 'single_textbox':
320 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_single", 'nolabel':"1" ,'colspan':"4"})
321 fields[tools.ustr(que.id) + "_single"] = {'type':'char', 'size': 255, 'string':"single_textbox", 'views':{}}
323 elif que_rec.type == 'comment':
324 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_comment", 'nolabel':"1" ,'colspan':"4"})
325 fields[tools.ustr(que.id) + "_comment"] = {'type':'text', 'string':"Comment/Eassy Box", 'views':{}}
327 elif que_rec.type == 'table':
328 xml_group = etree.SubElement(xml_group, 'group', {'col': str(len(que_rec.column_heading_ids)), 'colspan': '4'})
329 for col in que_rec.column_heading_ids:
330 etree.SubElement(xml_group, 'separator', {'string': tools.ustr(col.title),'colspan': '1'})
331 for row in range(0,que_rec.no_of_rows):
332 for col in que_rec.column_heading_ids:
333 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_table_" + tools.ustr(col.id) +"_"+ tools.ustr(row), 'nolabel':"1"})
334 fields[tools.ustr(que.id) + "_table_" + tools.ustr(col.id) +"_"+ tools.ustr(row)] = {'type':'char','size':255,'views':{}}
336 elif que_rec.type == 'multiple_textboxes_diff_type':
337 xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
339 if ans.type == "email" :
340 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
341 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'widget':'email','width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
343 etree.SubElement(xml_group, 'field', {'readonly': str(readonly), 'width':"300",'colspan': '1','name': tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"})
344 if ans.type == "char" :
345 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'char', 'size':255, 'string':ans.answer}
346 elif ans.type in ['integer','float','date','datetime']:
347 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type': str(ans.type), 'string':ans.answer}
351 for item in ans.menu_choice.split('\n'):
352 if item and not item.strip() == '': selection.append((item ,item))
353 fields[tools.ustr(que.id) + "_" + tools.ustr(ans.id) + "_multi"] = {'type':'selection', 'selection' : selection, 'string':ans.answer}
355 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:
356 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:
357 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_otherfield", 'colspan':"4"})
358 fields[tools.ustr(que.id) + "_otherfield"] = {'type':'boolean', 'string':que_rec.comment_label, 'views':{}}
359 if que_rec.comment_field_type == 'char':
360 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
361 fields[tools.ustr(que.id) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
362 elif que_rec.comment_field_type == 'text':
363 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
364 fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
366 if que_rec.comment_field_type == 'char':
367 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
368 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
369 fields[tools.ustr(que.id) + "_other"] = {'type': 'char', 'string': '', 'size':255, 'views':{}}
370 elif que_rec.comment_field_type == 'text':
371 etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(que_rec.comment_label)),'colspan':"4"})
372 etree.SubElement(xml_group, 'field', {'readonly' :str(readonly), 'name': tools.ustr(que.id) + "_other", 'nolabel':"1" ,'colspan':"4"})
373 fields[tools.ustr(que.id) + "_other"] = {'type': 'text', 'string': '', 'views':{}}
375 xml_footer = etree.SubElement(xml_form, 'footer', {'col': '8', 'colspan': '1', 'width':"100%"})
378 etree.SubElement(xml_footer, 'label', {'string': ""})
379 etree.SubElement(xml_footer, 'button', {'name':"action_previous",'string':_('Previous'),'type':"object"})
380 but_string = _('Next')
381 if int(page_number) + 1 == total_pages:
382 but_string = _('Done')
383 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)):
384 etree.SubElement(xml_footer, 'label', {'string': ""})
385 etree.SubElement(xml_footer, 'button', {'special' : 'cancel','string': tools.ustr("Done") ,'context' : tools.ustr(context), 'class':"oe_highlight"})
386 elif context.has_key('active') and context.get('active', False) and int(page_number) + 1 == total_pages and context.has_key('response_id'):
387 etree.SubElement(xml_footer, 'label', {'string': ""})
388 etree.SubElement(xml_footer, 'button', {'name':"action_forward_next",'string': tools.ustr("Next Answer") ,'type':"object",'context' : tools.ustr(context), 'class':"oe_highlight"})
389 elif context.has_key('active') and context.get('active',False) and int(page_number) + 1 == total_pages:
390 etree.SubElement(xml_footer, 'label', {'string': ""})
391 etree.SubElement(xml_footer, 'button', {'special': "cancel", 'string' : 'Done', 'context' : tools.ustr(context), 'class':"oe_highlight"})
393 etree.SubElement(xml_footer, 'label', {'string': ""})
394 etree.SubElement(xml_footer, 'button', {'name':"action_next",'string': tools.ustr(but_string) ,'type':"object",'context' : tools.ustr(context), 'class':"oe_highlight"})
395 etree.SubElement(xml_footer, 'label', {'string': _('or')})
396 etree.SubElement(xml_footer, 'button', {'special': "cancel",'string':_('Exit'),'class':"oe_link"})
397 etree.SubElement(xml_footer, 'label', {'string': tools.ustr(page_number+ 1) + "/" + tools.ustr(total_pages), 'class':"oe_survey_title_page oe_right"})
399 root = xml_form.getroottree()
400 result['arch'] = etree.tostring(root)
401 result['fields'] = fields
402 result['context'] = context
404 survey_obj.write(cr, SUPERUSER_ID, survey_id, {'tot_comp_survey' : sur_rec.tot_comp_survey + 1})
405 sur_response_obj.write(cr, uid, int(sur_name_read.response), {'state' : 'done'})
407 # mark the survey request as done; call 'survey_req_done' on its actual model
408 survey_req_obj = self.pool.get(context.get('active_model'))
409 if survey_req_obj and hasattr(survey_req_obj, 'survey_req_done'):
410 survey_req_obj.survey_req_done(cr, uid, context.get('active_ids', []), context=context)
412 if sur_rec.send_response:
413 survey_data = survey_obj.browse(cr, uid, survey_id)
414 response_id = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))['response']
415 report = self.create_report(cr, uid, [survey_id], 'report.survey.browse.response', survey_data.title,context)
417 pdf_filename = addons.get_module_resource('survey', 'report') + survey_data.title + ".pdf"
418 if os.path.exists(pdf_filename):
419 file = open(pdf_filename)
422 line = file.readline()
427 attachments[survey_data.title + ".pdf"] = file_data
429 os.remove(addons.get_module_resource('survey', 'report') + survey_data.title + ".pdf")
430 context.update({'response_id':response_id})
431 user_email = user_obj.browse(cr, uid, uid, context).email
432 resp_email = survey_data.responsible_id and survey_data.responsible_id.email or False
434 if user_email and resp_email:
435 user_name = user_obj.browse(cr, uid, uid, context=context).name
436 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."
437 vals = {'state': 'outgoing',
438 'subject': "Survey Answer Of " + user_name,
439 'body_html': '<pre>%s</pre>' % mail,
440 'email_to': [resp_email],
441 'email_from': user_email}
443 vals['attachment_ids'] = [(0,0,{'name': a_name,
444 'datas_fname': a_name,
445 'datas': str(a_content).encode('base64')})
446 for a_name, a_content in attachments.items()]
447 self.pool.get('mail.mail').create(cr, uid, vals, context=context)
449 xml_form = etree.Element('form', {'string': _('Complete Survey Answer')})
450 xml_footer = etree.SubElement(xml_form, 'footer', {'col': '6', 'colspan': '4' ,'class': 'oe_survey_title_height'})
452 etree.SubElement(xml_form, 'separator', {'string': 'Survey Completed', 'colspan': "4"})
453 etree.SubElement(xml_form, 'label', {'string': 'Thanks for your Answer'})
454 etree.SubElement(xml_form, 'newline')
455 etree.SubElement(xml_footer, 'button', {'special':"cancel",'string':"OK",'colspan':"2",'class':'oe_highlight'})
456 root = xml_form.getroottree()
457 result['arch'] = etree.tostring(root)
458 result['fields'] = {}
459 result['context'] = context
462 def create_report(self, cr, uid, res_ids, report_name=False, file_name=False, context=None):
464 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.
466 if not report_name or not res_ids:
467 return (False, Exception('Report name and Resources ids are required !!!'))
470 service = netsvc.LocalService(report_name);
471 (result, format) = service.create(cr, uid, res_ids, {}, context)
472 ret_file_name = addons.get_module_resource('survey', 'report') + file_name + '.pdf'
473 fp = open(ret_file_name, 'wb+');
477 # hr.applicant: if survey answered directly in system: attach report to applicant
478 if context.get('active_model') == 'hr.applicant':
479 self.pool.get('hr.applicant').write(cr,uid,[context.get('active_ids')[0]],{'response':context.get('response_id')})
480 result = base64.b64encode(result)
481 file_name = file_name + '.pdf'
482 ir_attachment = self.pool.get('ir.attachment').create(cr, uid,
485 'datas_fname': file_name,
486 'res_model': context.get('active_model'),
487 'res_id': context.get('active_ids')[0]},
491 return (False, str(e))
492 return (True, ret_file_name)
494 def default_get(self, cr, uid, fields_list, context=None):
496 Assign Default value in particular field. If Browse Answers wizard run then read the value into database and Assigne to a particular fields.
501 for field in fields_list:
502 if field.split('_')[0] == 'progress':
503 tot_page_id = self.pool.get('survey').browse(cr, uid, context.get('survey_id',False))
504 tot_per = (float(100) * (int(field.split('_')[2]) + 1) / len(tot_page_id.page_ids))
505 value[field] = tot_per
506 response_obj = self.pool.get('survey.response')
507 surv_name_wiz = self.pool.get('survey.name.wiz')
508 if context.has_key('response_id') and context.get('response_id') and int(context['response_id'][0]) > 0:
509 data = super(survey_question_wiz, self).default_get(cr, uid, fields_list, context)
510 response_ans = response_obj.browse(cr, uid, context['response_id'][context['response_no']])
513 for que in response_ans.question_ids:
514 for field in fields_list:
515 if field.split('_')[0] != "progress" and field.split('_')[0] == str(que.question_id.id):
516 if que.response_answer_ids and len(field.split('_')) == 4 and field.split('_')[1] == "commentcolumn" and field.split('_')[3] == "field":
517 for ans in que.response_answer_ids:
518 if str(field.split('_')[2]) == str(ans.answer_id.id):
519 value[field] = ans.comment_field
521 if que.response_table_ids and len(field.split('_')) == 4 and field.split('_')[1] == "table":
522 for ans in que.response_table_ids:
523 if str(field.split('_')[2]) == str(ans.column_id.id) and str(field.split('_')[3]) == str(ans.name):
524 value[field] = ans.value
526 if que.comment and (field.split('_')[1] == "comment" or field.split('_')[1] == "other"):
527 value[field] = tools.ustr(que.comment)
529 elif que.single_text and field.split('_')[1] == "single":
530 value[field] = tools.ustr(que.single_text)
532 elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[1] == "selection":
533 for ans in que.response_answer_ids:
534 if str(field.split('_')[2]) == str( ans.answer_id.id):
535 value[field] = str(ans.column_id.id)
537 elif que.response_answer_ids and len(field.split('_')) == 2 and field.split('_')[1] == "selection":
538 value[field] = str(que.response_answer_ids[0].answer_id.id)
540 elif que.response_answer_ids and len(field.split('_')) == 3 and field.split('_')[2] != "multi" and field.split('_')[2] != "numeric":
541 for ans in que.response_answer_ids:
542 if str(field.split('_')[1]) == str( ans.answer_id.id) and str(field.split('_')[2]) == str(ans.column_id.id):
544 value[field] = ans.value_choice
549 for ans in que.response_answer_ids:
550 if str(field.split('_')[1]) == str( ans.answer_id.id):
551 value[field] = ans.answer
555 if not context.has_key('sur_name_id'):
557 if context.has_key('active') and context.get('active',False):
559 sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False))
562 for key,val in safe_eval(sur_name_read.get('store_ans',"{}")).items():
563 for field in fields_list:
564 if field in list(val):
565 value[field] = val[field]
568 def create(self, cr, uid, vals, context=None):
570 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.
572 if context is None: context = {}
574 survey_question_wiz_id = super(survey_question_wiz,self).create(cr, uid, {'name': vals.get('name')}, context=context)
575 if context.has_key('active') and context.get('active',False):
576 return survey_question_wiz_id
578 for key,val in vals.items():
579 if key.split('_')[0] == "progress":
581 if not context.has_key('sur_name_id') and key.split('_')[0] == "wizardid":
582 context.update({'sur_name_id': int(key.split('_')[1])})
587 surv_name_wiz = self.pool.get('survey.name.wiz')
588 surv_all_resp_obj = self.pool.get('survey.response')
589 surv_tbl_column_obj = self.pool.get('survey.tbl.column.heading')
590 survey_obj = self.pool.get('survey')
591 resp_obj = self.pool.get('survey.response.line')
592 res_ans_obj = self.pool.get('survey.response.answer')
593 que_obj = self.pool.get('survey.question')
594 sur_name_read = surv_name_wiz.read(cr, uid, context.get('sur_name_id',False), [])
597 if not sur_name_read['response']:
598 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']})
599 surv_name_wiz.write(cr, uid, [context.get('sur_name_id', False)], {'response' : tools.ustr(response_id)})
601 response_id = int(sur_name_read['response'])
603 if response_id not in surv_all_resp_obj.search(cr, uid, []):
604 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)})
605 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'response' : tools.ustr(response_id)})
607 #click first time on next button then increemnet on total start suvey
608 if not safe_eval(sur_name_read['store_ans']):
609 his_id = self.pool.get('survey.history').create(cr, uid, {'user_id': uid, \
610 'date': strftime('%Y-%m-%d %H:%M:%S'), 'survey_id': sur_name_read['survey_id'][0]})
611 survey_id = sur_name_read['survey_id'][0]
612 sur_rec = survey_obj.read(cr, uid, survey_id)
613 survey_obj.write(cr, SUPERUSER_ID, survey_id, {'tot_start_survey' : sur_rec['tot_start_survey'] + 1})
614 if context.has_key('cur_id'):
615 if context.has_key('request') and context.get('request',False):
616 self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
617 self.pool.get(context.get('object',False)).survey_req_done(cr, uid, [int(context.get('cur_id'))], context)
619 self.pool.get(context.get('object',False)).write(cr, uid, [int(context.get('cur_id',False))], {'response' : response_id})
620 if sur_name_read['store_ans'] and type(safe_eval(sur_name_read['store_ans'])) == dict:
621 sur_name_read['store_ans'] = safe_eval(sur_name_read['store_ans'])
622 for key,val in sur_name_read['store_ans'].items():
624 if field.split('_')[0] == val['question_id']:
626 click_update.append(key)
629 sur_name_read['store_ans'] = {}
633 for key, val in vals.items():
634 que_id = key.split('_')[0]
635 if que_id not in que_li:
636 que_li.append(que_id)
637 que_rec = que_obj.read(cr, uid, [int(que_id)], [])[0]
639 'question_id': que_id,
640 'date_create': datetime.datetime.now(),
642 'response_id': response_id
644 resp_id = resp_obj.create(cr, uid, res_data)
645 resp_id_list.append(resp_id)
646 sur_name_read['store_ans'].update({resp_id:{'question_id':que_id}})
647 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
652 comment_field = False
653 comment_value = False
656 for key1, val1 in vals.items():
657 if val1 and key1.split('_')[1] == "table" and key1.split('_')[0] == que_id:
658 surv_tbl_column_obj.create(cr, uid, {'response_table_id' : resp_id,'column_id':key1.split('_')[2], 'name':key1.split('_')[3], 'value' : val1})
659 sur_name_read['store_ans'][resp_id].update({key1:val1})
662 elif val1 and key1.split('_')[1] == "otherfield" and key1.split('_')[0] == que_id:
664 sur_name_read['store_ans'][resp_id].update({key1:val1})
666 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
669 elif val1 and key1.split('_')[1] == "selection" and key1.split('_')[0] == que_id:
670 if len(key1.split('_')) > 2:
671 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'column_id' : val1})
672 selected_value.append(val1)
673 response_list.append(str(ans_create_id) + "_" + str(key1.split('_')[-1]))
675 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':val1})
676 sur_name_read['store_ans'][resp_id].update({key1:val1})
679 elif key1.split('_')[1] == "other" and key1.split('_')[0] == que_id:
684 if que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_specific_length':
685 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']:
687 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
690 if que_rec['comment_valid_type'] == 'must_be_whole_number':
692 if value < que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
694 elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
696 if value < que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
698 elif que_rec['comment_valid_type'] == 'must_be_date':
699 value = datetime.datetime.strptime(val1, "%Y-%m-%d")
700 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"):
704 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_email_address':
706 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
709 for res in resp_id_list:
710 sur_name_read['store_ans'].pop(res)
711 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['comment_valid_err_msg']))
713 resp_obj.write(cr, uid, resp_id, {'comment':val1})
714 sur_name_read['store_ans'][resp_id].update({key1:val1})
716 elif val1 and key1.split('_')[1] == "comment" and key1.split('_')[0] == que_id:
717 resp_obj.write(cr, uid, resp_id, {'comment':val1})
718 sur_name_read['store_ans'][resp_id].update({key1:val1})
721 elif val1 and key1.split('_')[0] == que_id and (key1.split('_')[1] == "single" or (len(key1.split('_')) > 2 and key1.split('_')[2] == 'multi')):
723 if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
724 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']:
726 elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
729 if que_rec['validation_type'] == 'must_be_whole_number':
731 if value < que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
733 elif que_rec['validation_type'] == 'must_be_decimal_number':
735 if value < que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
737 elif que_rec['validation_type'] == 'must_be_date':
738 value = datetime.datetime.strptime(val1, "%Y-%m-%d")
739 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"):
743 elif que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_email_address':
745 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val1) == None:
748 for res in resp_id_list:
749 sur_name_read['store_ans'].pop(res)
750 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['validation_valid_err_msg']))
752 if key1.split('_')[1] == "single" :
753 resp_obj.write(cr, uid, resp_id, {'single_text':val1})
755 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
757 sur_name_read['store_ans'][resp_id].update({key1:val1})
760 elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) > 2 and key1.split('_')[2] == 'numeric':
763 numeric_sum += int(val1)
764 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'answer' : val1})
765 sur_name_read['store_ans'][resp_id].update({key1:val1})
768 for res in resp_id_list:
769 sur_name_read['store_ans'].pop(res)
770 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + _("Please enter an integer value."))
772 elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 3:
773 if type(val1) == type('') or type(val1) == type(u''):
774 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})
775 sur_name_read['store_ans'][resp_id].update({key1:val1})
777 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[1], 'column_id' : key1.split('_')[2]})
778 sur_name_read['store_ans'][resp_id].update({key1:True})
780 matrix_list.append(key1.split('_')[0] + '_' + key1.split('_')[1])
783 elif val1 and que_id == key1.split('_')[0] and len(key1.split('_')) == 2:
784 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':resp_id, 'answer_id':key1.split('_')[-1], 'answer' : val1})
785 sur_name_read['store_ans'][resp_id].update({key1:val1})
787 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
789 for key,val in vals.items():
790 if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == que_id:
791 for res_id in response_list:
792 if key.split('_')[2] in res_id.split('_')[1]:
793 a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
794 sur_name_read['store_ans'][resp_id].update({key:val})
796 if comment_field and comment_value:
797 for res in resp_id_list:
798 sur_name_read['store_ans'].pop(res)
799 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['make_comment_field_err_msg']))
801 if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
802 for res in resp_id_list:
803 sur_name_read['store_ans'].pop(res)
804 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "'\n" + _("You cannot select the same answer more than one time."))
807 resp_obj.write(cr, uid, resp_id, {'state':'skip'})
809 if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
810 for res in resp_id_list:
811 sur_name_read['store_ans'].pop(res)
812 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg']))
814 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']:
816 if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
817 (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
818 (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
819 (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
820 (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'])):
821 for res in resp_id_list:
822 sur_name_read['store_ans'].pop(res)
823 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
825 elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
826 (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
827 (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
828 (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
829 (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
830 for res in resp_id_list:
831 sur_name_read['store_ans'].pop(res)
832 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
834 if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and que_rec['is_require_answer'] and select_count <= 0:
835 for res in resp_id_list:
836 sur_name_read['store_ans'].pop(res)
837 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
841 for update in click_update:
842 que_rec = que_obj.read(cr, uid , [int(sur_name_read['store_ans'][update]['question_id'])], [])[0]
843 res_ans_obj.unlink(cr, uid,res_ans_obj.search(cr, uid, [('response_id', '=', update)]))
844 surv_tbl_column_obj.unlink(cr, uid,surv_tbl_column_obj.search(cr, uid, [('response_table_id', '=', update)]))
845 resp_id_list.append(update)
846 sur_name_read['store_ans'].update({update:{'question_id':sur_name_read['store_ans'][update]['question_id']}})
847 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
852 comment_field = False
853 comment_value = False
856 for key, val in vals.items():
857 ans_id_len = key.split('_')
858 if ans_id_len[0] == sur_name_read['store_ans'][update]['question_id']:
859 if val and key.split('_')[1] == "table":
860 surv_tbl_column_obj.create(cr, uid, {'response_table_id' : update,'column_id':key.split('_')[2], 'name':key.split('_')[3], 'value' : val})
861 sur_name_read['store_ans'][update].update({key:val})
862 resp_obj.write(cr, uid, update, {'state': 'done'})
864 elif val and key.split('_')[1] == "otherfield" :
866 sur_name_read['store_ans'][update].update({key:val})
868 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans':sur_name_read['store_ans']})
871 elif val and key.split('_')[1] == "selection":
872 if len(key.split('_')) > 2:
873 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':key.split('_')[-1], 'column_id' : val})
874 selected_value.append(val)
875 response_list.append(str(ans_create_id) + "_" + str(key.split('_')[-1]))
877 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id': val})
878 resp_obj.write(cr, uid, update, {'state': 'done'})
879 sur_name_read['store_ans'][update].update({key:val})
882 elif key.split('_')[1] == "other":
887 if que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_specific_length':
888 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']:
890 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
892 if que_rec['comment_valid_type'] == 'must_be_whole_number':
894 if value < que_rec['comment_minimum_no'] or value > que_rec['comment_maximum_no']:
896 elif que_rec['comment_valid_type'] == 'must_be_decimal_number':
898 if value < que_rec['comment_minimum_float'] or value > que_rec['comment_maximum_float']:
900 elif que_rec['comment_valid_type'] == 'must_be_date':
901 value = datetime.datetime.strptime(val, "%Y-%m-%d")
902 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"):
906 elif que_rec['is_comment_require'] and que_rec['comment_valid_type'] == 'must_be_email_address':
908 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
911 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['comment_valid_err_msg']))
912 resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
913 sur_name_read['store_ans'][update].update({key:val})
915 elif val and key.split('_')[1] == "comment":
916 resp_obj.write(cr, uid, update, {'comment':val,'state': 'done'})
917 sur_name_read['store_ans'][update].update({key:val})
920 elif val and (key.split('_')[1] == "single" or (len(key.split('_')) > 2 and key.split('_')[2] == 'multi')):
922 if que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_specific_length':
923 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']:
925 elif que_rec['is_validation_require'] and que_rec['validation_type'] in ['must_be_whole_number', 'must_be_decimal_number', 'must_be_date']:
928 if que_rec['validation_type'] == 'must_be_whole_number':
930 if value < que_rec['validation_minimum_no'] or value > que_rec['validation_maximum_no']:
932 elif que_rec['validation_type'] == 'must_be_decimal_number':
934 if value < que_rec['validation_minimum_float'] or value > que_rec['validation_maximum_float']:
936 elif que_rec['validation_type'] == 'must_be_date':
937 value = datetime.datetime.strptime(val, "%Y-%m-%d")
938 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"):
942 elif que_rec['is_validation_require'] and que_rec['validation_type'] == 'must_be_email_address':
944 if re.match("^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", val) == None:
947 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' \n" + tools.ustr(que_rec['validation_valid_err_msg']))
948 if key.split('_')[1] == "single" :
949 resp_obj.write(cr, uid, update, {'single_text':val,'state': 'done'})
951 resp_obj.write(cr, uid, update, {'state': 'done'})
952 ans_create_id = res_ans_obj.create(cr, uid, {'response_id':update, 'answer_id':ans_id_len[1], 'answer' : val})
953 sur_name_read['store_ans'][update].update({key:val})
956 elif val and len(key.split('_')) > 2 and key.split('_')[2] == 'numeric':
959 numeric_sum += int(val)
960 resp_obj.write(cr, uid, update, {'state': 'done'})
961 ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[1], 'answer' : val})
962 sur_name_read['store_ans'][update].update({key:val})
965 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "'\n" + _("Please enter an integer value."))
967 elif val and len(key.split('_')) == 3:
968 resp_obj.write(cr, uid, update, {'state': 'done'})
969 if type(val) == type('') or type(val) == type(u''):
970 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})
971 sur_name_read['store_ans'][update].update({key:val})
973 ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[1], 'column_id' : ans_id_len[2]})
974 sur_name_read['store_ans'][update].update({key:True})
975 matrix_list.append(key.split('_')[0] + '_' + key.split('_')[1])
978 elif val and len(key.split('_')) == 2:
979 resp_obj.write(cr, uid, update, {'state': 'done'})
980 ans_create_id = res_ans_obj.create(cr, uid, {'response_id': update, 'answer_id':ans_id_len[-1], 'answer' : val})
981 sur_name_read['store_ans'][update].update({key:val})
983 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'store_ans': sur_name_read['store_ans']})
985 for key,val in vals.items():
986 if val and key.split('_')[1] == "commentcolumn" and key.split('_')[0] == sur_name_read['store_ans'][update]['question_id']:
987 for res_id in response_list:
988 if key.split('_')[2] in res_id.split('_')[1]:
989 a = res_ans_obj.write(cr, uid, [res_id.split('_')[0]], {'comment_field':val})
990 sur_name_read['store_ans'][update].update({key:val})
992 if comment_field and comment_value:
993 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['make_comment_field_err_msg']))
995 if que_rec['type'] == "rating_scale" and que_rec['rating_allow_one_column_require'] and len(selected_value) > len(list(set(selected_value))):
996 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "\n" + _("You cannot select same answer more than one time.'"))
998 if que_rec['numeric_required_sum'] and numeric_sum > que_rec['numeric_required_sum']:
999 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['numeric_required_sum_err_msg']))
1001 if not select_count:
1002 resp_obj.write(cr, uid, update, {'state': 'skip'})
1004 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']:
1006 if (que_rec['required_type'] == 'all' and len(list(set(matrix_list))) < len(que_rec['answer_choice_ids'])) or \
1007 (que_rec['required_type'] == 'at least' and len(list(set(matrix_list))) < que_rec['req_ans']) or \
1008 (que_rec['required_type'] == 'at most' and len(list(set(matrix_list))) > que_rec['req_ans']) or \
1009 (que_rec['required_type'] == 'exactly' and len(list(set(matrix_list))) != que_rec['req_ans']) or \
1010 (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'])):
1011 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
1013 elif (que_rec['required_type'] == 'all' and select_count < len(que_rec['answer_choice_ids'])) or \
1014 (que_rec['required_type'] == 'at least' and select_count < que_rec['req_ans']) or \
1015 (que_rec['required_type'] == 'at most' and select_count > que_rec['req_ans']) or \
1016 (que_rec['required_type'] == 'exactly' and select_count != que_rec['req_ans']) or \
1017 (que_rec['required_type'] == 'a range' and (select_count < que_rec['minimum_req_ans'] or select_count > que_rec['maximum_req_ans'])):
1018 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
1020 if que_rec['type'] in ['multiple_choice_only_one_ans','single_textbox','comment'] and que_rec['is_require_answer'] and select_count <= 0:
1021 raise osv.except_osv(_('Warning!'), "'" + que_rec['question'] + "' " + tools.ustr(que_rec['req_error_msg']))
1023 return survey_question_wiz_id
1025 def action_new_question(self, cr, uid, ids, context=None):
1027 New survey.Question form.
1031 for key,val in context.items():
1032 if type(key) == type(True):
1034 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),\
1035 ('name','=','survey_question_wizard_test')])
1037 'view_type': 'form',
1038 "view_mode": 'form',
1039 'res_model': 'survey.question',
1040 'type': 'ir.actions.act_window',
1043 'page_id': int(context.get('page_id',0)),
1047 def action_new_page(self, cr, uid, ids, context=None):
1049 New survey.Page form.
1053 for key,val in context.items():
1054 if type(key) == type(True):
1056 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),\
1057 ('name','=','survey_page_wizard_test')])
1059 'view_type': 'form',
1060 "view_mode": 'form',
1061 'res_model': 'survey.page',
1062 'type': 'ir.actions.act_window',
1068 def action_edit_page(self, cr, uid, ids, context=None):
1074 for key,val in context.items():
1075 if type(key) == type(True):
1077 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.page'),\
1078 ('name','=','survey_page_wizard_test')])
1080 'view_type': 'form',
1081 "view_mode": 'form',
1082 'res_model': 'survey.page',
1083 'type': 'ir.actions.act_window',
1085 'res_id': int(context.get('page_id',0)),
1090 def action_delete_page(self, cr, uid, ids, context=None):
1096 for key,val in context.items():
1097 if type(key) == type(True):
1100 self.pool.get('survey.page').unlink(cr, uid, [context.get('page_id',False)])
1101 for survey in self.pool.get('survey').browse(cr, uid, [context.get('survey_id',False)], context=context):
1102 if not survey.page_ids:
1103 return {'type':'ir.actions.act_window_close'}
1105 search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),\
1106 ('name','=','Survey Search')])
1107 surv_name_wiz = self.pool.get('survey.name.wiz')
1108 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], \
1109 {'transfer':True, 'page_no' : context.get('page_number',False) })
1111 'view_type': 'form',
1112 "view_mode": 'form',
1113 'res_model': 'survey.question.wiz',
1114 'type': 'ir.actions.act_window',
1116 'search_view_id':search_id[0],
1120 def action_edit_question(self, cr, uid, ids, context=None):
1122 Edit survey.question.
1126 for key,val in context.items():
1127 if type(key) == type(True):
1129 view_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question'),\
1130 ('name','=','survey_question_wizard_test')])
1132 'view_type': 'form',
1133 "view_mode": 'form',
1134 'res_model': 'survey.question',
1135 'type': 'ir.actions.act_window',
1137 'res_id' : int(context.get('question_id',0)),
1142 def action_delete_question(self, cr, uid, ids, context=None):
1144 Delete survey.question.
1148 for key,val in context.items():
1149 if type(key) == type(True):
1152 que_obj = self.pool.get('survey.question')
1153 que_obj.unlink(cr, uid, [context.get('question_id',False)])
1154 search_id = self.pool.get('ir.ui.view').search(cr,uid,[('model','=','survey.question.wiz'),\
1155 ('name','=','Survey Search')])
1156 surv_name_wiz = self.pool.get('survey.name.wiz')
1157 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)],\
1158 {'transfer':True, 'page_no' : context.get('page_number',0) })
1160 'view_type': 'form',
1161 "view_mode": 'form',
1162 'res_model': 'survey.question.wiz',
1163 'type': 'ir.actions.act_window',
1165 'search_view_id': search_id[0],
1169 def action_forward_previous(self, cr, uid, ids, context=None):
1171 Goes to previous Survey Answer.
1175 search_obj = self.pool.get('ir.ui.view')
1176 surv_name_wiz = self.pool.get('survey.name.wiz')
1177 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1178 ('name','=','Survey Search')])
1179 wiz_id = surv_name_wiz.create(cr,uid, {'survey_id': context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0})
1180 context.update({'sur_name_id' :wiz_id, 'response_no': context.get('response_no',0) - 1})
1182 if context.get('response_no',0) + 1 > len(context.get('response_id',0)):
1185 'view_type': 'form',
1186 "view_mode": 'form',
1187 'res_model': 'survey.question.wiz',
1188 'type': 'ir.actions.act_window',
1190 'search_view_id': search_id[0],
1194 def action_forward_next(self, cr, uid, ids, context=None):
1196 Goes to Next Survey Answer.
1200 search_obj = self.pool.get('ir.ui.view')
1201 surv_name_wiz = self.pool.get('survey.name.wiz')
1202 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1203 ('name','=','Survey Search')])
1204 wiz_id = surv_name_wiz.create(cr,uid, {'survey_id' : context.get('survey_id',False),'page_no' :-1,'page':'next','transfer' :1,'response':0})
1205 context.update({'sur_name_id' :wiz_id, 'response_no' : context.get('response_no',0) + 1})
1207 if context.get('response_no',0) + 1 > len(context.get('response_id',0)):
1210 'view_type': 'form',
1211 "view_mode": 'form',
1212 'res_model': 'survey.question.wiz',
1213 'type': 'ir.actions.act_window',
1215 'search_view_id': search_id[0],
1219 def action_next(self, cr, uid, ids, context=None):
1225 surv_name_wiz = self.pool.get('survey.name.wiz')
1226 search_obj = self.pool.get('ir.ui.view')
1227 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),('name','=','Survey Search')])
1228 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'next'})
1230 'view_type': 'form',
1231 "view_mode": 'form',
1232 'res_model': 'survey.question.wiz',
1233 'type': 'ir.actions.act_window',
1235 'search_view_id': search_id[0],
1239 def action_previous(self, cr, uid, ids, context=None):
1241 Goes to previous page.
1245 surv_name_wiz = self.pool.get('survey.name.wiz')
1246 search_obj = self.pool.get('ir.ui.view')
1247 search_id = search_obj.search(cr,uid,[('model','=','survey.question.wiz'),\
1248 ('name','=','Survey Search')])
1249 surv_name_wiz.write(cr, uid, [context.get('sur_name_id',False)], {'transfer':True, 'page':'previous'})
1251 'view_type': 'form',
1252 "view_mode": 'form',
1253 'res_model': 'survey.question.wiz',
1254 'type': 'ir.actions.act_window',
1256 'search_view_id': search_id[0],
1260 survey_question_wiz()
1262 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: